Pandas 中每个类别的日期时间滚动计数

Datetime rolling count per category in Pandas

从具有 dateuser 列的 DataFrame 开始,我想添加第三个 count_past_5_days 列以指示每行用户在过去 5 天:

date user count_past_5_days
2020-01-01 abc 1
2020-01-01 def 1
2020-01-02 abc 2
2020-01-03 abc 3
2020-01-04 abc 4
2020-01-04 def 2
2020-01-04 ghi 1
2020-01-05 abc 5
2020-01-06 abc 5
2020-01-07 abc 5

我试过以下方法:

df.set_index('date').rolling('5D')['user'].count()

但这会获取过去五个滚动日的总计数,而不仅仅是当前行的特定用户。如何仅针对每一行的特定用户获取此滚动计数?

试试这个,你可以将 rolling 链接到 groupby:

df.set_index('date').groupby('user')['user']\
  .rolling('5D')\
  .count()\
  .rename('count_past_5_days')\
  .reset_index()\
  .sort_values('date')

输出:

  user       date  count_past_5_days
0  abc 2020-01-01                1.0
1  def 2020-01-01                1.0
2  abc 2020-01-02                2.0
3  abc 2020-01-03                3.0
4  abc 2020-01-04                4.0
5  def 2020-01-04                2.0
6  ghi 2020-01-04                1.0
7  abc 2020-01-05                5.0
8  abc 2020-01-06                5.0
9  abc 2020-01-07                5.0

您可以对所有值为 1 的 'dummy' 列进行求和。这与 pd.crosstab 在幕后使用的方法相同 - 尽管我们可以直接命名我们的输出列。

out = (
    df.assign(count_past_5_days=1)
    .groupby('user')
    .rolling('5D', on='date')['count_past_5_days']
    .sum()
)

print(out)
user  date      
abc   2020-01-01    1.0
      2020-01-02    2.0
      2020-01-03    3.0
      2020-01-04    4.0
      2020-01-05    5.0
      2020-01-06    5.0
      2020-01-07    5.0
def   2020-01-01    1.0
      2020-01-04    2.0
ghi   2020-01-04    1.0
Name: count_past_5_days, dtype: float64

这会输出一个值与您想要的值相对应的系列。如果您希望您的输出在视觉上与您的输入对齐,您可以使用以下任何一种...

  • out.sort_index(level='date').reset_index()
  • out.reset_index().sort_values('date')
  • out.reindex(pd.MultiIndex.from_frame(df).swaplevel()).reset_index()

请注意,如果您的数据碰巧未排序,选项 3 将保留数据的原始顺序。

>>> out.sort_index(level='date').reset_index()
  user       date  count_past_5_days
0  abc 2020-01-01                1.0
1  def 2020-01-01                1.0
2  abc 2020-01-02                2.0
3  abc 2020-01-03                3.0
4  abc 2020-01-04                4.0
5  def 2020-01-04                2.0
6  ghi 2020-01-04                1.0
7  abc 2020-01-05                5.0
8  abc 2020-01-06                5.0
9  abc 2020-01-07                5.0