Python 如何将自定义滚动功能应用于pandas groupby?

Python 如何将自定义滚动功能应用于pandas groupby?,python,pandas,Python,Pandas,我想使用以下函数从平均销售额计算每日销售额: def derive_daily_sales(avg_sales_series, period, first_day_sales): """ derive the daily sales from previous_avg_sales start date to current_avg_sales end date for detail formula, please refer to READM

我想使用以下函数从平均销售额计算每日销售额:

def derive_daily_sales(avg_sales_series, period, first_day_sales):
    """
    derive the daily sales from previous_avg_sales start date to current_avg_sales end date
    for detail formula, please refer to README.md

    @avg_sales_series: an array of avg  sales(e.g. 2020-08-04 to 2020-08-06)
    @period: the averaging period in days (e.g. 30 days, 90 days)
    @first_day_sales: the sales at the first day of previous_avg_sales
    """

    x_n1 = avg_sales_series[-1]*period - avg_sales_series[0]*period + first_day_sales

    return x_n1
avg_sales_系列
应该是熊猫系列

数据帧如下所示:

date, customer_id, avg_30_day_sales
12/08/2020, 1, 30
13/08/2020, 1, 40
14/08/2020, 1, 40
12/08/2020, 2, 20
13/08/2020, 2, 40
14/08/2020, 2, 30
我想先按
customer\u id
分组,然后按
date
排序。然后,获得大小为2的滚动窗口。并应用自定义函数
derivate_daily_sales
,假设
period
=30和
first_day_sales
等于first
avg_30_day_sales

我试过:

df_sales_grouped = df_sales.sort_values('date').groupby(['customer_id','date'])]

df_daily_sales['daily_sales'] = df_sales_grouped['avg_30_day_sales'].rolling(2).apply(derive_daily_sales, axis=1, period=30, first_day_sales= df_sales['avg_30_day_sales'][0])

您不应按日期分组,因为您希望滚动该列,因此分组应为:

df_sales_grouped = df_sales.sort_values('date').groupby('customer_id')
接下来,您实际要做的是在数据帧中的每个组上应用一个滚动窗口。因此,您需要使用
apply
两次,一次在分组的数据帧上,一次在每个滚动窗口上。这可以通过以下方式完成:

rolling_arguments = {'period': 30, 'first_day_sales': df_sales['avg_30_day_sales'][0]}
df_sales['daily_sales'] = df_sales_grouped['avg_30_day_sales'].apply(
    lambda g: g.rolling(2).apply(derive_daily_sales, kwargs=rolling_arguments))
对于给定的输入数据,结果为:

      date  customer_id  avg_30_day_sales  daily_sales
12/08/2020            1                30          NaN
13/08/2020            1                40        330.0
14/08/2020            1                40         30.0
12/08/2020            2                20          NaN
13/08/2020            2                40        630.0
14/08/2020            2                30       -270.0

但我有一个关键错误:-1。你知道吗?我在函数中使用
.iloc
解决了这个问题。输入不是一个数组,而是一个熊猫系列。@约翰:正确,这样做会使熊猫系列作为
derivate\u daily\u sales
的输入。如果需要数组,可以在输入上使用
.values
(或者像处理序列一样处理它,即使用
iloc
)。