python - groupby - Cómo aplicar funciones de balanceo en un grupo por objeto en pandas
pandas groupby count (3)
puedes hacerlo así:
>>> df
>>>
fruit amount
20140101 apple 3
20140102 apple 5
20140102 orange 10
20140104 banana 2
20140104 apple 10
20140104 orange 4
20140105 orange 6
20140105 grape 1
>>> g= df.set_index(''fruit'', append=True).groupby(level=1)
>>> res = g[''amount''].apply(pd.rolling_mean, 3, 1).reset_index(''fruit'')
>>> res
fruit 0
20140101 apple 3.000000
20140102 apple 4.000000
20140102 orange 10.000000
20140104 banana 2.000000
20140104 apple 6.000000
20140104 orange 7.000000
20140105 orange 6.666667
20140105 grape 1.000000
actualizar
Bueno, como @cphlewis se menciona en los comentarios, mi código no dará los resultados que desea. He verificado diferentes enfoques y el que encontré hasta ahora es algo como esto (sin embargo, no estoy seguro del rendimiento):
>>> df.index = [pd.to_datetime(str(x), format=''%Y%m%d'') for x in df.index]
>>> df.reset_index(inplace=True)
>>> def avg_3_days(x):
return df[(df[''index''] >= x[''index''] - pd.DateOffset(3)) & (df[''index''] < x[''index'']) & (df[''fruit''] == x[''fruit''])].amount.mean()
>>> df[''res''] = df.apply(avg_3_days, axis=1)
>>> df
index fruit amount res
0 2014-01-01 apple 3 NaN
1 2014-01-02 apple 5 3
2 2014-01-02 orange 10 NaN
3 2014-01-04 banana 2 NaN
4 2014-01-04 apple 10 4
5 2014-01-04 orange 4 10
6 2014-01-05 orange 6 7
7 2014-01-05 grape 1 NaN
Tengo dificultades para resolver un problema de revisión o reinicio en el marco de datos o quizás en grupo.
siguiente es un ejemplo simple de la dataframe que tengo:
fruit amount
20140101 apple 3
20140102 apple 5
20140102 orange 10
20140104 banana 2
20140104 apple 10
20140104 orange 4
20140105 orange 6
20140105 grape 1
…
20141231 apple 3
20141231 grape 2
Necesito calcular el valor promedio de ''cantidad'' de cada fruta en los 3 días anteriores para todos los días, y crear el siguiente marco de datos:
fruit average_in_last 3 days
20140104 apple 4
20140104 orange 10
...
por ejemplo en 20140104, los 3 días anteriores son 20140101, 20140102 y 20140103 (tenga en cuenta que la fecha en el marco de datos no es continua y 20140103 no existe), la cantidad promedio de manzana es (3 + 5) / 2 = 4 y naranja es 10/1 = 10, el resto es 0.
el marco de datos de muestra es muy simple, pero el marco de datos real es mucho más complicado y más grande. Espero que alguien pueda arrojar algo de luz sobre esto, gracias de antemano!
También quería usar rolling con groupby, por eso llegué a esta página, pero creo que tengo una solución que es mejor que las sugerencias anteriores.
Usted podría hacer lo siguiente:
pivoted_df = pd.pivot_table(df, index=''date'', columns=''fruits'', values=''amount'')
average_fruits = pivoted_df.rolling(window=3).mean().stack()
el .stack()
no es necesario, pero transformará su tabla pivote de nuevo a un df regular
Suponiendo que tenemos un marco de datos así al principio,
>>> df
fruit amount
2017-06-01 apple 1
2017-06-03 apple 16
2017-06-04 apple 12
2017-06-05 apple 8
2017-06-06 apple 14
2017-06-08 apple 1
2017-06-09 apple 4
2017-06-02 orange 13
2017-06-03 orange 9
2017-06-04 orange 9
2017-06-05 orange 2
2017-06-06 orange 11
2017-06-07 orange 6
2017-06-08 orange 3
2017-06-09 orange 3
2017-06-10 orange 13
2017-06-02 grape 14
2017-06-03 grape 16
2017-06-07 grape 4
2017-06-09 grape 15
2017-06-10 grape 5
>>> dates = [i.date() for i in pd.date_range(''2017-06-01'', ''2017-06-10'')]
>>> temp = (df.groupby(''fruit'')[''amount'']
.apply(lambda x: x.reindex(dates) # fill in the missing dates for each group)
.fillna(0) # fill each missing group with 0
.rolling(3)
.sum()) # do a rolling sum
.reset_index()
.rename(columns={''amount'': ''sum_of_3_days'',
''level_1'': ''date''})) # rename date index to date col
>>> temp.head()
fruit date amount
0 apple 2017-06-01 NaN
1 apple 2017-06-02 NaN
2 apple 2017-06-03 17.0
3 apple 2017-06-04 28.0
4 apple 2017-06-05 36.0
# converts the date index into date column
>>> df = df.reset_index().rename(columns={''index'': ''date''})
>>> df.merge(temp, on=[''fruit'', ''date''])
>>> df
date fruit amount sum_of_3_days
0 2017-06-01 apple 1 NaN
1 2017-06-03 apple 16 17.0
2 2017-06-04 apple 12 28.0
3 2017-06-05 apple 8 36.0
4 2017-06-06 apple 14 34.0
5 2017-06-08 apple 1 15.0
6 2017-06-09 apple 4 5.0
7 2017-06-02 orange 13 NaN
8 2017-06-03 orange 9 22.0
9 2017-06-04 orange 9 31.0
10 2017-06-05 orange 2 20.0
11 2017-06-06 orange 11 22.0
12 2017-06-07 orange 6 19.0
13 2017-06-08 orange 3 20.0
14 2017-06-09 orange 3 12.0
15 2017-06-10 orange 13 19.0
16 2017-06-02 grape 14 NaN
17 2017-06-03 grape 16 30.0
18 2017-06-07 grape 4 4.0
19 2017-06-09 grape 15 19.0
20 2017-06-10 grape 5 20.0