我有一个看起来像这样的数据框:
Datetime | Category | ID
--------------------------
2020-01-30 | A | 1
2020-02-01 | B | 1
2020-02-02 | A | 1
2020-02-20 | A | 1
2020-01-28 | B | 2
2020-01-29 | C | 2
2020-01-30 | C | 2
2020-01-31 | D | 2
2020-02-01 | D | 2
2020-02-02 | D | 2
2020-02-03 | C | 2
我想在该行(不包括当前行)的1周内获得每个ID的前2个最频繁的类别。熊猫有可能吗?我试图做.rolling和.value_counts,但似乎不起作用。谢谢!
下面是我要获取的数据框:
Datetime | Category | ID
--------------------------
2020-01-30 | NaN | 1
2020-02-01 | [A, ""] | 1
2020-02-02 | [A, B] | 1
2020-02-20 | NaN | 1
2020-01-28 | Nan | 2
2020-01-29 | [B,""] | 2
2020-01-30 | [B,C] | 2
2020-01-31 | [B,C] | 2
2020-02-01 | [C,D] | 2
2020-02-02 | [C,D] | 2
2020-02-03 | [C,D] | 2
谢谢!
修改 pd.get_dummies答案很好,但是由于我的数据集很大,因此效率不高。如果有人对此有一个有效的解决方案,将不胜感激!谢谢!
答案 0 :(得分:0)
您可以使用resample()
而不是rolling()
,因为您的时间索引频率是每天的,并且您需要每周的统计信息,因此请尝试以下操作:
df.groupby('ID').resample('1w').apply(lambda s: s.value_counts().head(2))
请注意,这仅在apply()
将数据剥离到pd.Series
而不是np.arrays
的Pandas版本中有效。另外,如果数据框中有更多列,则可能有必要在lambda函数中指定列名称,即:
df.groupby('ID').resample('1w').apply(lambda s: s['Category'].value_counts().head(2))
如果您需要排除窗口的第一行,请使用iloc[]
切片:
df.groupby('ID').resample('1w').apply(lambda s: s['Category'].iloc[1:].value_counts().head(2))