我有一个看起来像这样的 df:
time val
0 1
1 1
2 2
3 3
4 1
5 2
6 3
7 3
8 3
9 3
10 1
11 1
如何创建新列来保存条件发生且不发生变化的次数?在这种情况下,我想为 val
中的每个唯一值创建一个列,该列保存给定发生行的累积和,但如果条件不改变,则不会增加该值。
预期结果如下:
time val sum_1 sum_2 sum_3
0 1 1 0 0
1 1 1 0 0
2 2 1 1 0
3 3 1 1 1
4 1 2 1 1
5 2 2 2 1
6 3 2 2 2
7 3 2 2 2
8 3 2 2 2
9 3 2 2 2
10 1 3 2 2
11 1 3 2 2
编辑
更具体地说明条件:
我想计算val
中出现唯一值的次数。例如,使用下面的代码,我可以获得以下结果:
df['sum_1'] = (df['val'] == 1).cumsum()
df['sum_2'] = (df['val'] == 2).cumsum()
df['sum_3'] = (df['val'] == 3).cumsum()
time val sum_1 sum_2 sum_3
0 0 1 1 0 0
1 1 1 2 0 0
2 2 2 2 1 0
3 3 3 2 1 1
4 4 1 3 1 1
5 5 2 3 2 1
但是,此代码会计算条件的每次出现。例如,val
显示 1
总共出现了 3 次。但是,我想将连续出现的 1
视为一个组,仅计算连续出现的分组数。在上面的示例中,1
总共出现了 3 次,但作为连续分组只出现了 2 次。
最佳答案
您可以通过 &
链接掩码进行按位 AND
,通过比较 Series.ne
的移位值来测试第一个连续值。与 Series.shift
并运行代码来测试列 val
的所有唯一值:
uniq = df['val'].unique()
m = df['val'].ne(df['val'].shift())
for c in uniq:
df[f'sum_{c}'] = (df['val'].eq(c) & m).cumsum()
print (df)
time val sum_1 sum_2 sum_3
0 0 1 1 0 0
1 1 1 1 0 0
2 2 2 1 1 0
3 3 3 1 1 1
4 4 1 2 1 1
5 5 2 2 2 1
6 6 3 2 2 2
7 7 3 2 2 2
8 8 3 2 2 2
9 9 3 2 2 2
10 10 1 3 2 2
11 11 1 3 2 2
为了获得更好的性能(我希望),这里有 numpy 替代方案:
a = df['val'].to_numpy()
uniq = np.unique(a)
m = np.concatenate(([False], a[:-1])) != a
arr = np.cumsum((a[:, None] == uniq) & m[:, None], axis=0)
df = df.join(pd.DataFrame(arr, index=df.index, columns=uniq).add_prefix('sum_'))
print (df)
time val sum_1 sum_2 sum_3
0 0 1 1 0 0
1 1 1 1 0 0
2 2 2 1 1 0
3 3 3 1 1 1
4 4 1 2 1 1
5 5 2 2 2 1
6 6 3 2 2 2
7 7 3 2 2 2
8 8 3 2 2 2
9 9 3 2 2 2
10 10 1 3 2 2
11 11 1 3 2 2
关于python - 如何跟踪独特情况发生的次数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/67074844/