У меня есть датафрейм клиента с суммой и датой покупки. В этом случае у меня есть два клиента, A и B:

df1 = pd.DataFrame(index=pd.date_range('2015-04-24', periods = 50)).assign(purchase=[x for x in range(51,101)])
df2 = pd.DataFrame(index=pd.date_range('2015-04-28', periods = 50)).assign(purchase=[x for x in range(0,50)])

df3 = pd.concat([df1,df2], keys=['A','B'])

df3 = df3.rename_axis(['user','date']).reset_index()
print(df3.head())

  user       date  purchase
0    A 2015-04-24        51
1    A 2015-04-25        52
2    A 2015-04-26        53
3    A 2015-04-27        54
4    A 2015-04-28        55

Я просто хотел бы узнать средние недельные расходы пользователя, причем неделя с понедельника по воскресенье. Ожидаемый результат:

  user       average_weekly_spend 
0    A       51
1    B       60

Однако я не могу понять, как установить его с понедельника по воскресенье. Сейчас я использую resample с 7D. Это означает, что у всех клиентов будет другое определение недели, я думаю. Я считаю, что это занимает 7 дней с момента первой покупки и так далее. Таким образом, у каждого клиента будет своя дата начала.

df3.groupby('user').apply(lambda x: x.resample('7D', on='date').mean()).groupby('user')['purchase'].mean()


user
A    78.125
B    27.125

Можно ли определить мою собственную неделю с понедельника по воскресенье для всех клиентов?

2
SCool 19 Дек 2019 в 17:39

3 ответа

Кажется, вам нужна частота W-Mon:

df = (df3.groupby('user')
         .resample('W-Mon', on='date')['purchase']
         .mean()
         .mean(level=0)
         .reset_index())
print (df)
  user  purchase
0    A      75.5
1    B      28.7

Не уверен, что если здесь хорошее решение, используйте mean из mean s, возможно, вы можете получить счет и сумму с помощью resample, а затем создать средство по определению - суммы, разделенные на счетчики:

df = (df3.groupby('user')
         .resample('W-Mon', on='date')['purchase']
         .agg(['size','sum'])
         .sum(level=0))
df['mean'] = df.pop('sum') / df.pop('size')
print (df)
      mean
user      
A     75.5
B     24.5
5
jezrael 19 Дек 2019 в 14:56

Интересно, что другое решение с to_period дает другой ответ:

df3.groupby(['user',df3.date.dt.to_period('W-MON')]).mean().mean(level='user')

Выход:

      purchase
user          
A       75.500
B       27.125
2
Quang Hoang 19 Дек 2019 в 14:48

В Python диапазон дат уже проиндексирован с понедельника по воскресенье.

Если вы просто используете метод pandas.Series.dt.week для получения номера недели, это легко.

df3['week_number'] = df3['date'].dt.week
df3.head(20)

Вы можете проверить в df3 выше, неделя 18 начинается 2015-04-27, то есть понедельник.

df4 = df3.groupby(['user','week_number']).mean()

# Final mean
df4.groupby(['user']).mean()

Я думаю, что это правильные средние недельные расходы. Однако это не то же самое, что вы поделились в своем сообщении с ожидаемым результатом.

Output:

user    purchase
A   74.625
B   26.250
1
stargazer 19 Дек 2019 в 15:21