multiple groupby functions example columns python pandas group-by dataframe apply

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