python - Pandas 对每个类别的日期范围分别求和

标签 python pandas time-series grouping rolling-computation

我有一个数据框,其中包含不同商品的销售交易时间序列:

import pandas as pd
from datetime import timedelta
df_1 = pd.DataFrame()
df_2 = pd.DataFrame()
df_3 = pd.DataFrame()

# Create datetimes and data
df_1['date'] = pd.date_range('1/1/2018', periods=5, freq='D')
df_1['item'] = 1
df_1['sales']= 2

df_2['date'] = pd.date_range('1/1/2018', periods=5, freq='D')
df_2['item'] = 2
df_2['sales']= 3

df_3['date'] = pd.date_range('1/1/2018', periods=5, freq='D')
df_3['item'] = 3
df_3['sales']= 4

df = pd.concat([df_1, df_2, df_3])
df = df.sort_values(['item'])
df

结果数据框:

    date    item    sales
0   2018-01-01  1   2
1   2018-01-02  1   2
2   2018-01-03  1   2
3   2018-01-04  1   2
4   2018-01-05  1   2
0   2018-01-01  2   3
1   2018-01-02  2   3
2   2018-01-03  2   3
3   2018-01-04  2   3
4   2018-01-05  2   3
0   2018-01-01  3   4
1   2018-01-02  3   4
2   2018-01-03  3   4
3   2018-01-04  3   4
4   2018-01-05  3   4

我想计算给定时间窗口内给定商品的“销售额”总和。我无法使用 pandas roll.sum 因为时间序列稀疏(例如 2018-01-01 > 2018-01-04 > 2018-01-06 > 等)。

我尝试过这个解决方案(时间窗口 = 2 天):

df['start_date'] = df['date'] - timedelta(3)
df['end_date'] = df['date'] - timedelta(1)
df['rolled_sales'] = df.apply(lambda x: df.loc[(df.date >= x.start_date) & 
                                            (df.date <= x.end_date), 'sales'].sum(), axis=1)

但结果是给定时间窗口内所有商品的销售额总和:

    date    item    sales   start_date  end_date    rolled_sales
0   2018-01-01  1   2   2017-12-29  2017-12-31  0
1   2018-01-02  1   2   2017-12-30  2018-01-01  9
2   2018-01-03  1   2   2017-12-31  2018-01-02  18
3   2018-01-04  1   2   2018-01-01  2018-01-03  27
4   2018-01-05  1   2   2018-01-02  2018-01-04  27
0   2018-01-01  2   3   2017-12-29  2017-12-31  0
1   2018-01-02  2   3   2017-12-30  2018-01-01  9
2   2018-01-03  2   3   2017-12-31  2018-01-02  18
3   2018-01-04  2   3   2018-01-01  2018-01-03  27
4   2018-01-05  2   3   2018-01-02  2018-01-04  27
0   2018-01-01  3   4   2017-12-29  2017-12-31  0
1   2018-01-02  3   4   2017-12-30  2018-01-01  9
2   2018-01-03  3   4   2017-12-31  2018-01-02  18
3   2018-01-04  3   4   2018-01-01  2018-01-03  27
4   2018-01-05  3   4   2018-01-02  2018-01-04  27

我的目标是分别计算每个商品的rolled_sales,如下所示:

    date    item    sales   start_date  end_date    rolled_sales
0   2018-01-01  1   2   2017-12-29  2017-12-31  0
1   2018-01-02  1   2   2017-12-30  2018-01-01  2
2   2018-01-03  1   2   2017-12-31  2018-01-02  4
3   2018-01-04  1   2   2018-01-01  2018-01-03  6
4   2018-01-05  1   2   2018-01-02  2018-01-04  8
0   2018-01-01  2   3   2017-12-29  2017-12-31  0
1   2018-01-02  2   3   2017-12-30  2018-01-01  3
2   2018-01-03  2   3   2017-12-31  2018-01-02  6
3   2018-01-04  2   3   2018-01-01  2018-01-03  9
4   2018-01-05  2   3   2018-01-02  2018-01-04  12
0   2018-01-01  3   4   2017-12-29  2017-12-31  0
1   2018-01-02  3   4   2017-12-30  2018-01-01  4
2   2018-01-03  3   4   2017-12-31  2018-01-02  8
3   2018-01-04  3   4   2018-01-01  2018-01-03  12
4   2018-01-05  3   4   2018-01-02  2018-01-04  16

我尝试应用此处建议的解决方案:Pandas rolling sum for multiply values separately 但失败了。

有什么想法吗?

提前非常感谢:)

安迪

最佳答案

每件商品2天滚动窗口的总销售额:

z = df.sort_values('date').set_index('date').groupby('item').rolling('2d')['sales'].sum()

输出:

item  date      
1     2018-01-01    2.0
      2018-01-02    4.0
      2018-01-03    4.0
      2018-01-04    4.0
      2018-01-05    4.0
2     2018-01-01    3.0
      2018-01-02    6.0
      2018-01-03    6.0
      2018-01-04    6.0
      2018-01-05    6.0
3     2018-01-01    4.0
      2018-01-02    8.0
      2018-01-03    8.0
      2018-01-04    8.0
      2018-01-05    8.0
Name: sales, dtype: float64

每件商品最近 2 天的总销售额:

df[df.groupby('item').cumcount() < 2 ].groupby('item').sum()

每件商品在 start_date 和 end_date 之间的总销售额:

start_date = pd.to_datetime('2017-12-2')
end_date = pd.to_datetime('2018-12-2')
df[df['date'].between(start_date, end_date)].groupby('item')['sales'].sum()

关于python - Pandas 对每个类别的日期范围分别求和,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58521181/

相关文章:

r - HTS 包 : how to specify a network-like hierarchy of forecasts?

r - 将每日股票数据转换为时间序列对象时的问题

python - 如何将函数发送到远程 Pyro 对象

python - 在 Python 中随机化字符串列表的最佳方法

python - 如何像 `squareform` pd.DataFrame 一样索引压缩的 `Pandas` 矩阵? (Python 3)

python - 如何在 Pandas 列中查找并提取字符串的一部分并将其编码到新列中

python - 如何替换 pandas 中的间隙行

r - R 中的滞后变量

python - 如何以编程方式输入 telnet 的转义字符?

Python列表理解覆盖值