在 pandas groupby 中查找过去 30 天和 60 天的平均数量

Find the average of Quantity for last 30 days and 60 days in pandas groupby

创建数据框的代码。

import pandas as pd

z = pd.DataFrame({'VENDOR':['A','A','A','A','B','B'],
                  'PO_DATE':['2020-12-16','2020-12-02','2020-11-23','2020-11-09','2020-12-16','2020-11-02'],
                  'PO_QTY':[18,5,77,6,20,5]})
z['PO_DATE'] = pd.to_datetime(z['PO_DATE'])
z = z.sort_values(['VENDOR','PO_DATE']).reset_index(drop=True)
 
z1 = z.groupby(['VENDOR']).agg({'PO_DATE':'last'}).rename(columns = {'PO_DATE':'MAX_PO_DATE'})
z2 = pd.merge(z,z1, on = 'VENDOR')
z2['DURATION'] = (z2['MAX_PO_DATE'] - z2['PO_DATE']).dt.days

Dataframe 看起来像这样。

此数据框按供应商和 PO_DATE 级别分组。

我创建了 MAX_PO_DATE 和 DURATION(取 MAX_PO_DATE 和 PO_DATE 的差值)。

我需要为每条记录找出最近 30 天和最近 60 天 PO_QTY 的平均值。

例如:

在第一条记录中,第一条和第四条记录之间的日期差是37,但是对于第一条和第三条记录,它是23,不到30天,所以AVG_PO_QTY_30_DAYS是平均值PO_QTY 同一供应商的前 3 条记录是 (6+77+5)/3。

如果是60天,则为(6+77+5+18)/4,因为第1条记录到第4条记录的日期差小于60天。

你可以这样做:

首先,我更改了您的代码,因为我需要使用降序来轻松应用滚动 windows

import pandas as pd

z = pd.DataFrame({'VENDOR':['A','A','A','A','B','B'],
                  'PO_DATE':['2020-12-16','2020-12-02','2020-11-23','2020-11-09','2020-12-16','2020-11-02'],
                  'PO_QTY':[18,5,77,6,20,5]})
z['PO_DATE'] = pd.to_datetime(z['PO_DATE'])
z["MAX_PO_DATE"] = z.groupby(['VENDOR'])["PO_DATE"].transform("max")
z['DURATION'] = (z['MAX_PO_DATE'] - z['PO_DATE']).dt.days

#sort descending to use window correctly
z = z.sort_values(['VENDOR','PO_DATE'],ascending=False).reset_index(drop=True)

之后,如果我将日期设置为索引,我可以根据时间申请移动windows。

df = z # not necessary but i like the df name

last_30_df = df.set_index("PO_DATE").groupby("VENDOR")["PO_QTY"].rolling("30d").mean().reset_index()
last_30_df.rename(columns={"PO_QTY": "AVG_PO_QTY_30_DAYS"}, inplace=True)

last_60_df = df.set_index("PO_DATE").groupby("VENDOR")["PO_QTY"].rolling("60d").mean().reset_index()
last_60_df.rename(columns={"PO_QTY": "AVG_PO_QTY_60_DAYS"}, inplace=True)

df = df.merge(last_30_df,  how='left', left_on=['VENDOR','PO_DATE'], right_on = ['VENDOR','PO_DATE'])
df = df.merge(last_60_df,  how='left', left_on=['VENDOR','PO_DATE'], right_on = ['VENDOR','PO_DATE'])

df = df.sort_values(['VENDOR','PO_DATE']).reset_index(drop=True)

最后我们得到了这个: