панды группируются, затем фильтруются по дате, чтобы получить среднее значение

#python #pandas #dataframe #filter #mean

Вопрос:

Используя фреймы данных pandas, я пытаюсь получить среднее количество покупок за последние 90 дней для каждой строки(не включая саму текущую строку) на основе CustID, а затем добавить новый столбец «PurchaseMeanLast90Days».

Это код, который я пробовал, который неверен:

 group = df.groupby(['CustId'])
df['PurchaseMeanLast90Days'] = group.apply(lambda g: g[g['Date'] > (pd.DatetimeIndex(g['Date'])   pd.DateOffset(-90))])['Purchases'].mean()
 

Вот мои данные:

Указатель КастИд Дата Покупки
0 1 1/01/2021 5
1 1 1/12/2021 1
2 1 3/28/2021 2
3 1 4/01/2021 4
4 1 4/20/2021 2
5 1 5/01/2021 5
6 2 1/01/2021 1
7 2 2/01/2021 1
8 2 3/01/2021 2
9 2 4/01/2021 3

Например, индекс строки 5 включал бы эти строки в среднее значение() = 3,33

Указатель КастИд Дата Покупки
2 1 3/28/2021 2
3 1 4/01/2021 4
4 1 4/20/2021 2

Новый фрейм данных будет выглядеть так(я не делал вычисления для CustID=2):

Указатель КастИд Дата Покупки Покупка в течение 90 дней
0 1 1/09/2021 5 0
1 1 1/12/2021 1 5
2 1 3/28/2021 2 3
3 1 4/01/2021 4 2.67
4 1 4/20/2021 2 3.0
5 1 5/01/2021 5 3.33
6 2 1/01/2021 1
7 2 2/01/2021 1
8 2 3/01/2021 2
9 2 4/01/2021 3

Комментарии:

1. Вы уверены, что индекс 4 рассчитан правильно? Между 4/20/2021 и 1/12/2021 составляет 98 дней. Так и должно быть 3.0 , а не 2.33

2. Спасибо, исправлена ошибка

Ответ №1:

Вы можете выполнить скользящее вычисление:

 df["Date"] = pd.to_datetime(df["Date"], dayfirst=False)
df["PurchaseMeanLast90Days"] = (
    (
        df.groupby("CustId")
        .rolling("90D", min_periods=1, on="Date", closed="both")["Purchases"]
        .apply(lambda x: x.shift(1).sum() / (len(x) - 1))
    )
    .fillna(0)
    .values
)
print(df)
 

С принтами:

    Index  CustId       Date  Purchases  PurchaseMeanLast90Days
0      0       1 2021-01-01          5                0.000000
1      1       1 2021-01-12          1                5.000000
2      2       1 2021-03-28          2                3.000000
3      3       1 2021-04-01          4                2.666667
4      4       1 2021-04-20          2                3.000000
5      5       1 2021-05-01          5                2.666667
6      6       2 2021-01-01          1                0.000000
7      7       2 2021-02-01          1                1.000000
8      8       2 2021-03-01          2                1.000000
9      9       2 2021-04-01          3                1.333333