我有这个示例数据框:
ID,Action,Station
01,P,S1
01,R,S2
01,P,S1
01,R,S2
02,P,S2
02,R,S1
02,P,S2
02,R,S1
03,P,S2
03,R,S1
我的目标是计算Action
和Station
列中的发生模式,例如(P,R)等有序对和相应的Station
值。这样结果数据框将显示为:
S1,S2,2
S2,S1,3
因此要查找的模式是每个ID
的(P,R)元组(ID
的值可以重复)并在Station
中计数其频率。
到目前为止,我的尝试是按Action
和Station
进行分组,并获得它们的值计数:
g = df.groupby(['Station','ID'])['Action'].size()
并获得:
Station ID
S1 1 2
2 2
3 1
S2 1 2
2 2
3 1
Name: Action, dtype: int64
但是我仍然无法照顾(P,R)元组及其频率。
答案 0 :(得分:2)
一种方法是将P,R
按cumsum()
分组,然后使用cumcount
:
(df.assign(order=df.Action.eq('P')
.groupby(df['ID']) # this might not be necessary
.cumsum())
.groupby(['ID', 'order'])
.Station.agg(tuple)
.groupby('ID').value_counts()
)
输出:
ID Station
1 (S1, S2) 2
2 (S2, S1) 2
3 (S2, S1) 1
Name: Station, dtype: int64
答案 1 :(得分:2)
为每个ID中的成对行定义一个计数器。然后通过合并自身将P和R合并在一起,但在一帧中映射P-> R和R->P。删除重复项,因为第二行是多余的,然后获取大小。
之所以起作用,是因为每个ID的P和R成对出现,彼此排成一行
map()
df['idx'] = df.groupby('ID').cumcount()//2
m = (df.merge(df.assign(Action=df.Action.map({'P': 'R', 'R': 'P'})),
on=['ID', 'idx', 'Action'], suffixes=['_P', '_R'])
.drop_duplicates(['ID', 'idx']))
m.groupby(['Station_P', 'Station_R']).size()
作为参考,Station_P Station_R
S1 S2 2
S2 S1 3
dtype: int64
看起来像
m