我有一个满足以下条件的熊猫数据框:
我需要实现一个计数器列,该计数器列从一个组的第一个事件开始,并且仅在(counter <3 * numEvents)个时递增。
计数器只能递增3次,而不会发生其他事件。如果它在多个记录中停留在3的倍数上,那么一旦发生另一个允许它递增的事件,它仍然只需要递增1。
示例数据框
group date event numEvents Counter
A 2020-08-05 0 0 0
A 2020-08-06 1 1 1
A 2020-08-07 0 1 2
A 2020-08-08 0 1 3
A 2020-08-09 0 1 3
A 2020-08-10 0 1 3
A 2020-08-11 1 2 4
A 2020-08-12 0 2 5
A 2020-08-13 0 2 6
A 2020-08-14 0 2 6
B 2020-08-05 1 1 1
B 2020-08-06 1 2 2
B 2020-08-07 0 2 3
B 2020-08-08 0 2 4
B 2020-08-09 0 2 5
B 2020-08-10 0 2 6
B 2020-08-11 0 2 6
B 2020-08-12 0 2 6
B 2020-08-13 0 2 0
B 2020-08-14 0 2 0
用于生成示例数据框的代码
import pandas as pd
import datetime as datetime
base = datetime.datetime.today()
numdays = 10
date_list = [(base - datetime.timedelta(days=x)).date() for x in range(numdays)]
df = pd.DataFrame(columns=['group', 'date'])
for group in ['A', 'B']:
tmp = pd.DataFrame({'group': group, 'date': date_list})
df = df.append(tmp)
df = df.sort_values(['group', 'date'])
groupA_events = [0, 1, 0, 0, 0, 0, 1, 0, 0, 0]
groupB_events = [1, 1, 0, 0, 0, 0, 0, 0, 0, 0]
events = groupA_events + groupB_events
df['event'] = events
df['numEvents'] = df.groupby('group')['event'].cumsum()
df['Counter'] = [0, 1, 2, 3, 3, 3, 4, 5, 6, 6, 1, 2, 3, 4, 5, 6, 6, 6, 6, 6]
这里的主要问题是我无法弄清楚如何基于自身有条件地增加列。香港专业教育学院尝试使用.cumsum(),但还没有找到一种适用于这种情况的方法。
谢谢
答案 0 :(得分:0)
我不太了解获得预期结果所需的逻辑,但是这里有一些可能有用的技术。
.shift()
可以将一个值从较早(或更晚)的行带到当前行。df = pd.DataFrame(
{'x': [10, 20, 30, 40, 50, 60],
'flag_1': [True] * 3 + [False] * 3, 'flag_2': [True, False] * 3})
# get previous x and current x on same row
df['prev_x'] = df['x'].shift(1)
# multiply by boolean
df['y'] = df['x'] * df['flag_1']
# cumulative sum of boolean (conditional increment)
df['z'] = df['flag_2'].cumsum()
print(df)
x flag_1 flag_2 prev_x y z
0 10 True True NaN 10 1
1 20 True False 10.0 20 1
2 30 True True 20.0 30 2
3 40 False False 30.0 0 2
4 50 False True 40.0 0 3
5 60 False False 50.0 0 3
最后,将.transform(min)
和.min()
与groupby进行比较(使用transform会返回与原始数据帧相同的行数)。