Python 在具有条件增量的数据帧上使用cumcount
以数据帧为例Python 在具有条件增量的数据帧上使用cumcount,python,pandas,dataframe,group-by,pandas-groupby,Python,Pandas,Dataframe,Group By,Pandas Groupby,以数据帧为例 df = pd.DataFrame( [ ['A', 1], ['A', 1], ['B', 1], ['B', 0], ['A', 0], ['A', 1], ['B', 1] ], columns = ['key', 'cond']) 我想为每个键找到一个累积(运行)计数(从1开始),只有当组中的前一个值为cond==1时,我们才增加计数。当附加到上
df = pd.DataFrame(
[
['A', 1],
['A', 1],
['B', 1],
['B', 0],
['A', 0],
['A', 1],
['B', 1]
], columns = ['key', 'cond'])
我想为每个键
找到一个累积(运行)计数(从1开始),只有当组中的前一个值为cond==1时,我们才增加计数。当附加到上述数据帧时,将给出
df_result = pd.DataFrame(
[
['A', 1, 1],
['A', 1, 2],
['B', 1, 1],
['B', 0, 2],
['A', 0, 3],
['A', 1, 3],
['B', 1, 2]
], columns = ['key', 'cond'])
请注意,每个键
组中最后一行的cond
值基本上没有影响
只需做一个简单的分组
和cumcount
df.groupby('key').cumcount()
当然,不考虑前一个元素的cond
值。我怎样才能考虑到这一点
编辑
由于下面的一些解决方案在某些边缘情况下不起作用,我将给出一个更全面的数据框架进行测试
df = pd.DataFrame(
[
['A', 0],
['A', 1],
['A', 1],
['B', 1],
['B', 0],
['A', 0],
['A', 1],
['B', 1],
['B', 0]
], columns = ['key', 'cond'])
当附加真实结果时,应该给出
df_result = pd.DataFrame(
[
['A', 0, 1],
['A', 1, 1],
['A', 1, 2],
['B', 1, 1],
['B', 0, 2],
['A', 0, 3],
['A', 1, 3],
['B', 1, 2],
['B', 0, 3]
], columns = ['key', 'cond'])
与和结合使用
与自定义lambda函数一起使用,对于以前的值,如果可能的话,第一个值是每个键的0
,最后一个值是转换为int
,则用反填充替换第一个NaN
:
df['new'] = df.groupby('key')['cond'].apply(lambda x: x.shift().bfill().cumsum()).astype(int)
print (df)
key cond new
0 A 1 1
1 A 1 2
2 B 1 1
3 B 0 2
4 A 0 3
5 A 1 3
6 B 1 2
是的,我错过了“上一个”@CallCentreExecutive:Fixed now(可能比apply
:P)两个groupby呼叫?是的,我不知道。在我的数据集上,这比@CallCentreeExecutive解决方案快,但在给定的键所有cond
值都为0时失败,而且如果最后的cond
值为0,则也会失败。列cond
中只有1
和0
值。是的,这只是一个标志。谢谢,每个键的第一个值是否可能是0
?是的,第一个值可能是0.OK,然后需要b填充
当组中的第一个cond
值为0时,这似乎不起作用。在这种情况下,它从0开始,而不是从1开始。@rwolst-因此需要始终从1开始,如果第一个是1
或0
?是的,始终从1开始。然后,如果我们观察到一个cond=1
,组中的下一行将有一个更新的计数。@rwolst-然后需要coldspeed解决方案。
df
key cond new
0 A 1 1
1 A 1 2
2 B 1 1
3 B 0 2
4 A 0 3
5 A 1 3
6 B 1 2
df['cnt'] = df[df["cond"]==1].groupby('key').cumcount()+1
df['cnt'] = df.groupby('key')['cnt'].fillna(method='bfill')
df
# => key cond cnt
# 0 A 1 1.0
# 1 A 1 2.0
# 2 B 1 1.0
# 3 B 0 2.0
# 4 A 0 3.0
# 5 A 1 3.0
# 6 B 1 2.0
df['new'] = df.groupby('key')['cond'].apply(lambda x: x.shift().bfill().cumsum()).astype(int)
print (df)
key cond new
0 A 1 1
1 A 1 2
2 B 1 1
3 B 0 2
4 A 0 3
5 A 1 3
6 B 1 2