Скользящее среднее значение панд в зависимости от значения ряда - PullRequest
0 голосов
/ 14 ноября 2018

У меня есть следующий фрейм данных в пандах:

Visitor    Home     Visitor_rtg    Home_rtg
 Sixers    Celtics     83.4         100.7
 Thunder   Warriors    97.7         105.6
 Bucks     Hornets     110.2        109.2
 Pelicans  Sixers      88.1         89.2
 Hornets   Wizards     90.1         102.3

Что я хотел бы сделать, так это сохранить скользящее среднее значение rtg для каждой команды, независимо от того, дома они или нет. Так, например, в четвертом ряду шестерка home_rtg будет 86.3, потому что (83.4+89.2) / 2. И последний ряд Шершней будет 99.65, потому что (109.2+90.1)/2 Я нашел df.rolling(), но не могу понять, как заставить это рассчитывать только для каждой команды. Порядок также имеет значение, потому что я хочу отслеживать прогресс рейтинга в течение сезона.

Ожидаемый результат:

Visitor    Home     Visitor_rtg    Home_rtg
 Sixers    Celtics     83.4         100.7
 Thunder   Warriors    97.7         105.6
 Bucks     Hornets     110.2        109.2
 Pelicans  Sixers      88.1         *86.3
 Hornets   Wizards     *99.65        102.3

Ответы [ 3 ]

0 голосов
/ 15 ноября 2018

Не очень приятное решение:

df = pd.DataFrame([['Sixers', 'Celtics', 83.4, 100.7], 
                   ['Pelicans', 'Sixers', 88.1, 89.2]], 
                  columns=['Visitor', 'Home', 'Visitor_rtg', 'Home_rtg'])
melted = df.melt(['Visitor', 'Home'])
pd.concat([melted.loc[melted['variable'] == 'Visitor_rtg', ['Visitor', 'value']].rename(columns={'Visitor': 'Team'}), 
            melted.loc[melted['variable'] == 'Home_rtg', ['Home', 'value']].rename(columns={'Home': 'Team'})], 
           axis=0, 
           ignore_index=True
      ).groupby('Team').mean()
0 голосов
/ 15 ноября 2018

Вы можете использовать reshape в базовых numpy массивах для эффективного решения.


Шаг 1
Это требует некоторого изменения формы и, наконец, помещения данных в массив empty numpy.

home = df.iloc[:, [1,3]]
away = df.iloc[:, [0,2]]
total = np.empty((home.shape[0] * 2, home.shape[1]), dtype=object)
total[::2] = away
total[1::2] = home

Шаг 2
Теперь, когда мы отформатировали данные, мы можем использовать expanding.mean и немного изменить форму

d = pd.DataFrame({'team': total[:, 0], 'score': total[:, 1].astype(float)}) 
out = d.groupby('team').score.expanding().mean().reset_index().sort_values(by='level_1') 

pd.DataFrame(
    out[['team', 'score']].values.reshape(-1, 4)[:, [0,2,1,3]],
    columns=df.columns
)

    Visitor      Home Visitor_rtg Home_rtg
0    Sixers   Celtics        83.4    100.7
1   Thunder  Warriors        97.7    105.6
2     Bucks   Hornets       110.2    109.2
3  Pelicans    Sixers        88.1     86.3
4   Hornets   Wizards       99.65    102.3
0 голосов
/ 15 ноября 2018

stack + concat + groupby + mean

IIUC, вы можете stack ваш фрейм данных и groupby+ mean значения.Нет необходимости в rolling

f = df[['Visitor', 'Home']].stack().reset_index(drop=True)
s = df[['Visitor_rtg', 'Home_rtg']].stack().reset_index(drop=True)
pd.concat([f, s], axis=1).groupby(0)[1].mean()

Выходы

Bucks       110.2
Celtics     100.7
Hornet      109.2
Pelicans     88.1
Sixers       86.3
Thunder      97.7
Warriors    105.6
Name: 1, dtype: float64

Отредактированный ответ

Чтобы получить желаемый результат, вы можете использовать expanding (некатится), чтобы получить среднее значение и transform для трансляции обратно в каждый исходный ряд.В конце, просто reshape базовых значений вашего dataframe, чтобы получить окончательный результат

df2 = pd.concat([f, s], axis=1)
df2[1] = df2.groupby(0).transform(lambda s: s.expanding().mean())
pd.DataFrame(df2.values.reshape(-1,4), columns=df.columns)


    Visitor     Home    Visitor_rtg Home_rtg
0   Sixers      83.4    Celtics     100.7
1   Thunder     97.7    Warriors    105.6
2   Bucks       110.2   Hornets     109.2
3   Pelicans    88.1    Sixers      86.3
4   Hornets     99.65   Wizards     102.3
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...