我想为以下df执行当前Val的周期计数:
ID Day Val
111 7 x
111 6 x
111 5 y
111 4 y
111 3 x
111 2 x
111 1 x
222 6 x
222 5 x
222 4 x
222 3 x
222 2 y
222 1 y
333 3 z
333 2 z
333 1 z
444 2 y
444 1 y
555 3 z
555 2 y
555 1 x
结果将是:
ID Day Val freq
111 6 x 2
111 4 y 2
111 1 x 3
222 3 x 4
222 1 y 2
333 1 z 3
444 1 y 2
555 3 z 1
555 2 y 1
555 1 x 1
我试过了: df.groupby(['ID','Value'])。size()。reset_index(name ='freq')但这不会得到我想要的结果。我不确定如何将它们分组以获得理想的结果。
非常感谢! :)
答案 0 :(得分:1)
这是一种方式。
from itertools import groupby, accumulate
lst = [sum(1 for _ in group) for _, group in groupby(zip(df.ID, df.Val))]
cumsum = [i-1 for i in accumulate(lst)]
df.iloc[cumsum].assign(freq=lst)
# ID Day Val freq
# 1 111 6 x 2
# 3 111 4 y 2
# 6 111 1 x 3
# 10 222 3 x 4
# 12 222 1 y 2
# 15 333 1 z 3
# 17 444 1 y 2
# 18 555 3 z 1
# 19 555 2 y 1
# 20 555 1 x 1
答案 1 :(得分:1)
使用指标列然后分组并计数的另一种解决方案。
(
df.assign(FLAG=
df.apply(lambda x: np.nan if x.Val==df.Val.iloc[x.name-1]
else x.name, axis=1)
)
.ffill()
.fillna(0)
.groupby(['ID','FLAG','Val'])
.Day.agg(['min','count'])
.reset_index(level=[0,2])
.reset_index(level=0, drop=True)
.set_axis(['ID', 'Val', 'Day', 'freq'], axis=1, inplace=False)
.reindex(['ID', 'Day', 'Val', 'freq'], axis=1)
)
Out[265]:
ID Day Val freq
0 111 6 x 2
1 111 4 y 2
2 111 1 x 3
3 222 3 x 4
4 222 1 y 2
5 333 1 z 3
6 444 1 y 2
7 555 3 z 1
8 555 2 y 1
9 555 1 x 1
答案 2 :(得分:1)
你这里只需要一行:-)
df.assign(freq=(df.Val!=df.Val.shift()).ne(False).cumsum()).groupby(['ID','freq']).agg({'Val':'first','Day':'last','freq':'count'}).reset_index('ID')
Out[1297]:
ID Day Val freq
new
1 111 6 x 2
2 111 4 y 2
3 111 1 x 3
3 222 3 x 4
4 222 1 y 2
5 333 1 z 3
6 444 1 y 2
7 555 3 z 1
8 555 2 y 1
9 555 1 x 1