Получение процента по сравнению с аналогичным периодом предыдущего года - PullRequest
0 голосов
/ 08 мая 2018

Если у меня есть фрейм данных, в котором есть столбцы «count», «w», «c», «d» и «y» и пример данных выглядит так:

131    1    dir    mob    2017
244    1    dir    mob    2018
311    1    org    mob    2017
332    1    org    mob    2018
212    2    dir    dsk    2017
311    2    dir    dsk    2018
401    2    org    mob    2017
283    2    org    mob    2018

Каким образом можно получить процентное изменение значения 'count', сгруппированного по 'w', 'c', 'd', в 2018 году по сравнению с 2017 годом?

Ответы [ 2 ]

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

Ну, вы можете отсортировать ваши данные (как у вас уже есть), а затем рассчитать разницу как разницу между count и count.shift ().

Это различие мы присваиваем фрейму данных, где отбрасываем все дублированные строки и столбцы, которые нам не интересны:

import pandas as pd

data = '''\
count  w      c      d       y
131    1    dir    mob    2017
244    1    dir    mob    2018
311    1    org    mob    2017
332    1    org    mob    2018
212    2    dir    dsk    2017
311    2    dir    dsk    2018
401    2    org    mob    2017
283    2    org    mob    2018'''

df = pd.read_csv(pd.compat.StringIO(data), sep='\s+')

df.sort_values(by=['w','c','d','y'], inplace=True) # <--- sort values 

diff = (df['count'].shift(-1) - df['count'])/df['count'][::2] # <--- calculate % change

dfnew = df.drop_duplicates(('w','c','d')).drop(['y','count'],axis=1).assign(diff=diff)

print(dfnew)

Возвращает:

   w    c    d      diff
0  1  dir  mob  0.862595
2  1  org  mob  0.067524
4  2  dir  dsk  0.466981
6  2  org  mob -0.294264

Вы можете добавить этот верификатор, чтобы убедиться, что вы получили количество правильных столбцов:

sum(df[['w','c','d']].duplicated()) == len(df)/2  # <-- This should return True
0 голосов
/ 08 мая 2018

Вот 2 способа: первый (с agg) быстрее второго (transform), но ради наличия опций ....

Приятно то, что они могут иметь дело со случаями, в которых у вас есть более чем 2 года для сравнения между

Метод 1

Вы можете отсортировать ваш фрейм данных по y, затем использовать agg() с pct_change():

df['pct'] = df.sort_values('y').groupby(['w', 'c', 'd']).agg({'count':'pct_change'})

>>> df
   count  w    c    d     y       pct
0    131  1  dir  mob  2017       NaN
1    244  1  dir  mob  2018  0.862595
2    311  1  org  mob  2017       NaN
3    332  1  org  mob  2018  0.067524
4    212  2  dir  dsk  2017       NaN
5    311  2  dir  dsk  2018  0.466981
6    401  2  org  mob  2017       NaN
7    283  2  org  mob  2018 -0.294264

Метод 2

Аналогично, но с использованием transform() вместо agg:

df['pct'] = df.sort_values('y').groupby(['w', 'c', 'd']).transform(lambda x: x.pct_change())['count']

>>> df
   count  w    c    d     y       pct
0    131  1  dir  mob  2017       NaN
1    244  1  dir  mob  2018  0.862595
2    311  1  org  mob  2017       NaN
3    332  1  org  mob  2018  0.067524
4    212  2  dir  dsk  2017       NaN
5    311  2  dir  dsk  2018  0.466981
6    401  2  org  mob  2017       NaN
7    283  2  org  mob  2018 -0.294264
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...