Панды groupby означают для другого Dataframe - PullRequest
0 голосов
/ 17 мая 2018

Я новичок в Pandas и не до конца понимаю, как работает pd.groupby.

Скажем, у меня есть датафрейм с датой и временем:

Date          City    Sales  Price
2018-01-01     NY      100     1
2018-01-01     NY      120     2
2018-01-01     NY       85     1.4
2018-01-01     LA       90     1.5
2018-01-01     SF       90     1
2018-01-01     SF       75     1

2018-01-02     NY      110     2
2018-01-02     NY      130     1.8
2018-01-02     NY      190     1.1
2018-01-02     LA      100     0.9
2018-01-02     LA      110     1.2
2018-01-02     LA      120     1.0
2018-01-02     LA       50     1.8
2018-01-02     SF      120     1.1

2018-01-03     NY       90     1.1
2018-01-03     LA       90     1.5
...
and so on

Итак, у меня есть несколько городов и несколько продаж в каждом городе по разной цене. Мне нужен новый фрейм данных, который будет содержать статистику по дням Цена (средняя = Сумма (Цена) / N) и mean_weighted = SUMM (цена * продажи) / SUMM (продажи) или как вариант: нормальные параметры распределения) для каждого города и даты.

Так бы это выглядело

Date           NY_mean NY_mean_w LA_mean LA_mean_w SF_mean SF_mean_w 
2018-01-01     1.466      1.53      1.5     1.5       1       1
2018-01-02     1.633      1.54      1.03    and so on
2018-01-03     ...
2018-01-04     ...
2018-01-05     ...
...

Есть ли способ избежать фортрановских суммирований с вложенными циклами и подпрограммами? Я пытаюсь (только для среднего значения):

import datetime
import pandas as pd
data = pd.read_pickle('path/data.pkl') # here is original data

index = pd.date_range(start = '2013-01-01', end = '2015-12-31', freq='D')

names = data.City.unique() # unique names
data_stat = pd.DataFrame(index=index, columns=columns)
data_stat = data_stat.fillna(0)

for nm in names: # iterate by name
    print(nm)
    data_stat.name = data [(data.City == nm)].groupby(Data).Price.mean()
data_stat.head()

Но это дает мне NaN во всех клетках. Буду признателен за любую помощь в этом.

1 Ответ

0 голосов
/ 17 мая 2018

Использование:

df = (df.assign(W=df['Sales'].mul(df['Price']))
        .groupby(['Date','City']).agg({'Price':'mean', 'W':'sum', 'Sales':'sum'})
        .assign(WM = lambda x: x['PW'].div(x['Sales']))[['Price','WM']]
        .rename(columns={'Price':'MEAN'})
        .unstack()
        .swaplevel(0,1, axis=1)
        .sort_index(axis=1, level=0))

df.columns = df.columns.map('_'.join)
print (df)
            LA_MEAN     LA_WM   NY_MEAN     NY_WM  SF_MEAN  SF_WM
Date                                                             
2018-01-01    1.500  1.500000  1.466667  1.504918      1.0    1.0
2018-01-02    1.225  1.136842  1.633333  1.541860      1.1    1.1
2018-01-03    1.500  1.500000  1.100000  1.100000      NaN    NaN

Объяснение

  1. Первые несколько столбцов Sales и Price для нового столбца W с assign и div
  2. Затем groupby и агрегирование mean и sum с по именам столбцов
  3. Создать столбец WM на assign и снова разделить
  4. Выбор только необходимых столбцов по подмножеству [[]]
  5. Rename столбец Price
  6. Изменить на unstack
  7. swaplevel MultiIndex в столбцах
  8. sort_index - первый уровень MultiIndex
  9. Свести MultiIndex к именам столбцов по map и join
...