2016-01-10 7 views
1

Как и мой previous question, я хочу разбить блок данных по группам и применить вычисления.Уровни Groupby Pandas

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

import pandas as pd 
import numpy as np 

d = {'year' : [2000, 2000, 2000, 2000, 2001, 2001, 2001], 
'home': ['A', 'B', 'B', 'A', 'B', 'A', 'A'], 
'away': ['B', 'A', 'A', 'B', 'A', 'B', 'B'], 
'aw': [1, 0, 0, 0, 1, 0, np.nan], 
'hw': [0, 1, 0, 1, 0, 1, np.nan]} 

df = pd.DataFrame(d, columns=['home', 'away', 'hw', 'aw']) 
df.index = range(1, len(df) + 1) 
df.index.name = 'game' 

df = df.set_index(['hw', 'aw'], append=True).stack().reset_index().rename(columns={'level_3': 'role', 0: 'team'}).loc[:, 
['game', 'team', 'role', 'hw', 'aw']] 

def wins(row): 
    if row['role'] == 'home': 
     return row['hw'] 
    else: 
     return row['aw'] 
df['wins'] = df.apply(wins, axis=1) 

df['expanding_mean'] = df.groupby('team')['wins'].apply(lambda x: pd.expanding_mean(x).shift()) 

print df 

Выполнение вышеуказанного даст расширяющееся среднее значение по всей области данных. Но как мне заново начать расчет для каждого нового year?

Я попытался добавить year в столбцы = в декларации df, но он включен в role, что нежелательно. Мой разрыв в понимании находится в уровнях, поэтому любое просвещение оценивается.

Edit: желаемый результат ниже

game team role hw aw wins expanding_mean year 
0  1 A home 0 1  0    NaN 2000 
1  1 B away 0 1  1    NaN 2000 
2  2 B home 1 0  1  1.000000 2000 
3  2 A away 1 0  0  0.000000 2000 
4  3 B home 0 0  0  1.000000 2000 
5  3 A away 0 0  0  0.000000 2000 
6  4 A home 1 0  1  0.000000 2000 
7  4 B away 1 0  0  0.666667 2000 
8  5 B home 0 1  0    NaN 2001 
9  5 A away 0 1  1    NaN 2001 
10  6 A home 1 0  1  0.000000 2001 
11  6 B away 1 0  0  1.000000 2001 
12  7 A home NaN NaN NaN  0.500000 2001 
13  7 B away NaN NaN NaN  0.500000 2001 
+0

вы хотите expanding_mean за команду и за год? – MaxNoe

+0

Да. После этого я беру это и сливаюсь с исходным фреймворком данных. Я просто не могу понять, как использовать 'level' для включения' ['year', 'team'] 'в groupby – noblerthanoedipus

+0

вы можете группировать по двум столбцам с помощью:' df.groupby (['team', ' год ']) ' – MaxNoe

ответ

1

IIUC вы можете добавить year к df.groupby(['team', 'year']) и добавить столбец year в коде выше groupby с изменением level_3 к level_4 в функции rename, так как столбец year был добавлен в индекс:

import pandas as pd 
import numpy as np 

d = {'year' : [2000, 2000, 2000, 2000, 2001, 2001, 2001], 
'home': ['A', 'B', 'B', 'A', 'B', 'A', 'A'], 
'away': ['B', 'A', 'A', 'B', 'A', 'B', 'B'], 
'aw': [1, 0, 0, 0, 1, 0, np.nan], 
'hw': [0, 1, 0, 1, 0, 1, np.nan]} 

df = pd.DataFrame(d, columns=['home', 'away', 'hw', 'aw', 'year']) 
df.index = range(1, len(df) + 1) 
df.index.name = 'game' 

df = df.set_index(['hw', 'aw', 'year'], append=True).stack().reset_index().rename(columns={'level_4': 'role', 0: 'team'}).loc[:, 
['game', 'team', 'role', 'hw', 'aw', 'year']] 

def wins(row): 
    if row['role'] == 'home': 
     return row['hw'] 
    else: 
     return row['aw'] 
df['wins'] = df.apply(wins, axis=1) 

df['expanding_mean'] = df.groupby(['team', 'year'])['wins'].apply(lambda x: pd.expanding_mean(x).shift()) 
print df 

    game team role hw aw year wins expanding_mean 
0  1 A home 0 1 2000  0    NaN 
1  1 B away 0 1 2000  1    NaN 
2  2 B home 1 0 2000  1  1.000000 
3  2 A away 1 0 2000  0  0.000000 
4  3 B home 0 0 2000  0  1.000000 
5  3 A away 0 0 2000  0  0.000000 
6  4 A home 1 0 2000  1  0.000000 
7  4 B away 1 0 2000  0  0.666667 
8  5 B home 0 1 2001  0    NaN 
9  5 A away 0 1 2001  1    NaN 
10  6 A home 1 0 2001  1  1.000000 
11  6 B away 1 0 2001  0  0.000000 
12  7 A home NaN NaN 2001 NaN  1.000000 
13  7 B away NaN NaN 2001 NaN  0.000000 
+0

Спасибо. Я также попробовал, что вы предложили, но не изменил на 'level_4'. Как узнать, какие уровни представляют группы? Есть ли способ их просмотра? – noblerthanoedipus

+1

Это зависит от количества уровней мультииндекса. Сначала у вас есть один уровень, а затем добавьте следующие три - вместе четыре. – jezrael

2

groupby как year и team и использовать transform:

import pandas as pd 
import numpy as np 


d = { 
    'year': [2000, 2000, 2000, 2000, 2001, 2001, 2001], 
    'team': ['A', 'B', 'B', 'A', 'B', 'A', 'A'], 
    'value': [1, 0, 0, 1, 2, 3, 3], 
} 

df = pd.DataFrame(d) 

df['mean_per_team_and_year'] = df.groupby(['team', 'year']).transform('mean') 
print(df)