2014-09-18 3 views
0

Я новичок в Pandas и несколько потерял, что здесь делать. У меня есть dataframe импортированного из CSV, который (сильно упрощенный) выглядеть следующим образом:Pandas groupby - Увеличивает среднее значение по столбцу

date = ['2013-08-10','2013-08-10','2013-08-10','2013-08-10','2013-08-10', 
     '2013-08-10','2013-08-10','2013-08-10','2013-08-10','2013-08-10'] 
event = ['213','213','213','213','214','214','214','215','215','215'] 
side = ['A','B','B','B','A','B','A','B','A','B',] 
value = [0.193,0.193,0.092,0.027,0.027,0.058,0.027,0.079,0.193,0.159] 

df = pd.DataFrame(zip(event,date,side,value), 
        columns=['event','date','side','value']) 

    event  date side value 
0 213 2013-08-10 A 0.193 
1 213 2013-08-10 B 0.193 
2 213 2013-08-10 B 0.092 
3 213 2013-08-10 B 0.027 
4 214 2013-08-10 A 0.027 
5 214 2013-08-10 B 0.058 
6 214 2013-08-10 A 0.027 
7 215 2013-08-10 B 0.079 
8 215 2013-08-10 A 0.193 
9 215 2013-08-10 B 0.159 

То, что я хочу, чтобы суммировать значения, соответствующие каждую сторону для каждого события. Это я достиг с GroupBy:

groupby = df.groupby(['event','side']).sum() 

      value 
event side  
213 A  0.193 
     B  0.312 
214 A  0.054 
     B  0.058 
215 A  0.193 
     B  0.238 

Но я также хочу, чтобы добавить новый столбец с расширяющейся средней для каждой из сторон, как это:

  value 
event side   roll_mean 
213 A  0.193 0 
     B  0.312 0 
214 A  0.054 0.193 
     B  0.058 0.312 
215 A  0.193 0.124 
     B  0.238 0.185 

Обратите внимание, что каждое событие имеет две стороны, но это не всегда A и B. То, что я хочу, это что-то вроде функции mean.if от excel, которая вычисляет расширяющееся среднее для всех значений текущей стороны, применяемое ко всем предыдущим строкам. Любая помощь по этому поводу будет оценена по достоинству.

+0

какое окно вы думаете о скользящем средстве? И почему бы скользящее среднее было равным нулю по краям? Разве это не было бы нулевым, как не вычислимым? –

+0

Окно будет любым предыдущим событием, и да оно должно быть нулевым. –

ответ

2

Я думаю, вы действительно ищете расширяющееся среднее, а не скользящее среднее. Расширяющееся среднее учитывает каждое предыдущее значение. Начну, где вы остановились:

In [63]: res = df.groupby(['event','side']).sum() 
In [64]: res 
Out[64]: 
      value 
event side  
213 A  0.193 
     B  0.312 
214 A  0.054 
     B  0.058 
215 A  0.193 
     B  0.238 

Теперь мы хотим GroupBy side и принять расширяющаяся среднее:

In [65]: res['expanding_mean'] = res.groupby(level='side').apply(pd.expanding_mean).shift(2) 
In [66]: res 
Out[66]: 
      value expanding_mean 
event side      
213 A  0.193    NaN 
     B  0.312    NaN 
214 A  0.054   0.1930 
     B  0.058   0.3120 
215 A  0.193   0.1235 
     B  0.238   0.1850 

Ваш результат должен быть shift эд на 2, так как вы хотите, среднее значение для включите все предыдущие, а не текущие (убедитесь, что это то, что вы на самом деле хотите, это кажется немного забавным). Вы можете заменить shift(2) на len(res.index.levels[1]), чтобы сделать его более общим, если у вас более двух сторон.

+0

Не знал о расширении среднего. Это именно то, чего я хотел. Благодаря! –

+0

Как оказалось, это не то, что мне нужно. Позже в dataframe появляются разные стороны, чем A и B, что усложняет ситуацию. То, что мне нужно, это что-то вроде функции mean.if() excel, где условие состоит в том, что значение принадлежит одной стороне, A, B, C и т. Д. Надеюсь, вы понимаете. –

+0

То есть сдвиг не работает, так как отличительная сторона не появляется в каком-либо конкретном порядке. –

0

Я добавил больше «сторон» к вашему файлу данных, поэтому он работает, когда результаты не являются «A» или «B». Это то, что вы хотите?

import pandas as pd 
import numpy as np 
date = ['2013-08-10','2013-08-10','2013-08-10','2013-08-10','2013-08-10', 
     '2013-08-10','2013-08-10','2013-08-10','2013-08-10','2013-08-10'] 
event = ['213','213','213','213','214','214','214','215','215','215'] 
side = ['A','B','A','B','C','A','C','A','C','A',] 
value = [0.193,0.193,0.092,0.027,0.027,0.058,0.027,0.079,0.193,0.159] 

df = pd.DataFrame(list(zip(event,date,side,value)), 
       columns=['event','date','side','value']) 
print(df) 

event  date side value 
0 213 2013-08-10 A 0.193 
1 213 2013-08-10 B 0.193 
2 213 2013-08-10 A 0.092 
3 213 2013-08-10 B 0.027 
4 214 2013-08-10 C 0.027 
5 214 2013-08-10 A 0.058 
6 214 2013-08-10 C 0.027 
7 215 2013-08-10 A 0.079 
8 215 2013-08-10 C 0.193 
9 215 2013-08-10 A 0.159 


ds = df.groupby(['event','side']).sum() 
print(ds) 

     value 
event side  
213 A  0.285 
     B  0.220 
214 A  0.058 
     C  0.054 
215 A  0.238 
     C  0.193 

ds.reset_index(inplace=True) 
ds['exp_mean'] = np.NaN 
for s in ds.side.unique(): 
    ndx = ds[ds.side==s].index 
    ds.ix[ndx,'exp_mean'] = pd.expanding_mean(ds.ix[ndx,'value']).shift(1) 
ds.set_index(['event', 'side'], inplace=True, drop=True) 
print(ds) 

      value exp_mean 
event side     
213 A  0.285  NaN 
     B  0.220  NaN 
214 A  0.058 0.2850 
     C  0.054  NaN 
215 A  0.238 0.1715 
     C  0.193 0.0540 
Смежные вопросы