Pandas groupby с идентификацией элемента с максимальным значением в другом столбце - PullRequest
1 голос
/ 24 октября 2019

У меня есть датафрейм с результатами продаж товаров с разными правилами ценообразования:

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['item'] = [1, 1, 2, 2, 2]
df_1['date'] = pd.date_range('1/1/2018', periods=5, freq='D')
df_1['price_rule'] = ['a', 'b', 'a', 'b', 'b']
df_1['sales']= [2, 4, 1, 5, 7]
df_1['clicks']= [7, 8, 9, 10, 11]

df_2['item'] = [1, 1, 2, 2, 2]
df_2['date'] = pd.date_range('1/1/2018', periods=5, freq='D')
df_2['price_rule'] = ['b', 'b', 'a', 'a', 'a']
df_2['sales']= [2, 3, 4, 5, 6]
df_2['clicks']= [7, 8, 9, 10, 11]

df_3['item'] = [1, 1, 2, 2, 2]
df_3['date'] = pd.date_range('1/1/2018', periods=5, freq='D')
df_3['price_rule'] = ['b', 'a', 'b', 'a', 'b']
df_3['sales']= [6, 5, 4, 5, 6]
df_3['clicks']= [7, 8, 9, 10, 11]

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

Это приводит к:

    item    date    price_rule  sales   clicks
0   1   2018-01-01       a       2       7
0   1   2018-01-01       b       2       7
0   1   2018-01-01       b       6       7
1   1   2018-01-02       b       4       8
1   1   2018-01-02       b       3       8
1   1   2018-01-02       a       5       8
2   2   2018-01-03       a       1       9
2   2   2018-01-03       a       4       9
2   2   2018-01-03       b       4       9
3   2   2018-01-04       b       5       10
3   2   2018-01-04       a       5       10
3   2   2018-01-04       a       5       10
4   2   2018-01-05       b       7       11
4   2   2018-01-05       a       6       11
4   2   2018-01-05       b       6       11

Моя цель:
1. группавсе элементы по дням (чтобы получить по одной строке для каждого элемента и заданного дня)
2. агрегировать 'клики' с "суммой"
3. генерировать столбцы "victory_pricing_rule" следующим образом:
- для данного товара и данной даты возьмите правило ценообразования с наибольшим значением «продаж» - в случае «розыгрыша» (см., Например: позиция 2 на 2018-01-03 в примере выше): выберите простоодин из них (это редко встречается в моем наборе данных, поэтому он может быть случайным ...)

Я представляю, что результат будет выглядеть следующим образом:

  item  date       winning_price_rule   clicks
0   1   2018-01-01      b               21
1   1   2018-01-02      a               24
2   2   2018-01-03      b               27  <<remark: could also be a (due to draw)
3   2   2018-01-04      a               30  <<remark: could also be b (due to draw)
4   2   2018-01-05      b               33

Я пытался:

a.groupby(['item', 'date'], as_index = False).agg({'sales':'sum','revenue':'max'})

, но не удалось определить выигрышное правило ценообразования.

Есть идеи? Большое спасибо за помощь:)

Энди

1 Ответ

1 голос
/ 24 октября 2019

Первый преобразовать столбец price_rule в индекс по DataFrame.set_index, поэтому для winning_price_rule возможно использование DataFrameGroupBy.idxmax - получить значение индекса по максимуму sales in GroupBy.agg, потому что также необходим агрегат sum:

df1 = (df.set_index('price_rule')
         .groupby(['item', 'date'])
         .agg({'sales':'idxmax', 'clicks':'sum'})
         .reset_index())

Для панд 0,25. + Возможно использование:

df1 = (df.set_index('price_rule')
         .groupby(['item', 'date'])
         .agg(winning_pricing_rule=pd.NamedAgg(column='sales', aggfunc='idxmax'),clicks=pd.NamedAgg(column='clicks', aggfunc="sum'))
         .reset_index())
...