¿Cuál es la diferencia entre pandas agg y función de aplicación?

No puedo entender la diferencia entre las funciones .aggregate y .apply Pandas.
Tome como ejemplo lo siguiente: cargue un conjunto de datos, groupby un groupby , defino una función simple y el usuario .agg o .apply .

Como puede ver, la statement de impresión dentro de mi función produce el mismo resultado después de usar .agg y .apply . El resultado, por otro lado, es diferente. ¿Porqué es eso?

 import pandas import pandas as pd iris = pd.read_csv('iris.csv') by_species = iris.groupby('Species') def f(x): ...: print type(x) ...: print x.head(3) ...: return 1 

Utilizando apply :

 by_species.apply(f) # # Sepal.Length Sepal.Width Petal.Length Petal.Width Species #0 5.1 3.5 1.4 0.2 setosa #1 4.9 3.0 1.4 0.2 setosa #2 4.7 3.2 1.3 0.2 setosa # # Sepal.Length Sepal.Width Petal.Length Petal.Width Species #0 5.1 3.5 1.4 0.2 setosa #1 4.9 3.0 1.4 0.2 setosa #2 4.7 3.2 1.3 0.2 setosa # # Sepal.Length Sepal.Width Petal.Length Petal.Width Species #50 7.0 3.2 4.7 1.4 versicolor #51 6.4 3.2 4.5 1.5 versicolor #52 6.9 3.1 4.9 1.5 versicolor # # Sepal.Length Sepal.Width Petal.Length Petal.Width Species #100 6.3 3.3 6.0 2.5 virginica #101 5.8 2.7 5.1 1.9 virginica #102 7.1 3.0 5.9 2.1 virginica #Out[33]: #Species #setosa 1 #versicolor 1 #virginica 1 #dtype: int64 

Usando agg

 by_species.agg(f) # # Sepal.Length Sepal.Width Petal.Length Petal.Width Species #0 5.1 3.5 1.4 0.2 setosa #1 4.9 3.0 1.4 0.2 setosa #2 4.7 3.2 1.3 0.2 setosa # # Sepal.Length Sepal.Width Petal.Length Petal.Width Species #50 7.0 3.2 4.7 1.4 versicolor #51 6.4 3.2 4.5 1.5 versicolor #52 6.9 3.1 4.9 1.5 versicolor # # Sepal.Length Sepal.Width Petal.Length Petal.Width Species #100 6.3 3.3 6.0 2.5 virginica #101 5.8 2.7 5.1 1.9 virginica #102 7.1 3.0 5.9 2.1 virginica #Out[34]: # Sepal.Length Sepal.Width Petal.Length Petal.Width #Species #setosa 1 1 1 1 #versicolor 1 1 1 1 #virginica 1 1 1 1 

apply aplica la función a cada grupo (sus Species ). Su función devuelve 1, por lo que termina con 1 valor para cada uno de los 3 grupos.

agg agrega cada columna (característica) para cada grupo, por lo que usted termina con un valor por columna por grupo.

Lee los documentos del grupo, son muy útiles. También hay un montón de tutoriales flotando alrededor de la web.

( Nota: estas comparaciones son relevantes para los objetos DataframeGroupby )

Algunas ventajas plausibles de usar .agg () en comparación con .apply (), para los objetos DataFrame GroupBy serían:

1) .agg () brinda la flexibilidad de aplicar múltiples funciones a la vez , o pasar una lista de funciones a cada columna.

2) También, aplicando diferentes funciones a la vez a diferentes columnas de dataframe.

Eso significa que tienes bastante control sobre cada columna con cada operación.

Aquí está el enlace para obtener más información: http://pandas.pydata.org/pandas-docs/version/0.13.1/groupby.html

Sin embargo, la función de aplicación podría limitarse para aplicar una función a cada columna del dataframe a la vez. Por lo tanto, es posible que deba llamar a la función de aplicación repetidamente para llamar a diferentes operaciones a la misma columna.

Aquí hay algunos ejemplos de comparación para .apply () vs .agg () para los objetos DataframeGroupBy:

Veamos, primero, las operaciones usando .apply ():

 In [261]: df = pd.DataFrame({"name":["Foo", "Baar", "Foo", "Baar"], "score_1":[5,10,15,10], "score_2" :[10,15,10,25], "score_3" : [10,20,30,40]}) In [262]: df Out[262]: name score_1 score_2 score_3 0 Foo 5 10 10 1 Baar 10 15 20 2 Foo 15 10 30 3 Baar 10 25 40 In [263]: df.groupby(["name", "score_1"])["score_2"].apply(lambda x : x.sum()) Out[263]: name score_1 Baar 10 40 Foo 5 10 15 10 Name: score_2, dtype: int64 In [264]: df.groupby(["name", "score_1"])["score_2"].apply(lambda x : x.min()) Out[264]: name score_1 Baar 10 15 Foo 5 10 15 10 Name: score_2, dtype: int64 In [265]: df.groupby(["name", "score_1"])["score_2"].apply(lambda x : x.mean()) Out[265]: name score_1 Baar 10 20.0 Foo 5 10.0 15 10.0 Name: score_2, dtype: float64 

Ahora, mira las mismas operaciones usando .agg () sin esfuerzo:

 In [274]: df = pd.DataFrame({"name":["Foo", "Baar", "Foo", "Baar"], "score_1":[5,10,15,10], "score_2" :[10,15,10,25], "score_3" : [10,20,30,40]}) In [275]: df Out[275]: name score_1 score_2 score_3 0 Foo 5 10 10 1 Baar 10 15 20 2 Foo 15 10 30 3 Baar 10 25 40 In [276]: df.groupby(["name", "score_1"]).agg({"score_3" :[np.sum, np.min, np.mean, np.max], "score_2":lambda x : x.mean()}) Out[276]: score_2 score_3  sum amin mean amax name score_1 Baar 10 20 60 20 30 40 Foo 5 10 10 10 10 10 15 10 30 30 30 30 

Por lo tanto, .agg () podría ser realmente útil para manejar los objetos DataFrameGroupBy, en comparación con .apply (). Pero, si está manejando únicamente objetos de dataframe puro, y no objetos DataFrameGroupBy, apply () puede ser muy útil, ya que apply () puede aplicar una función a lo largo de cualquier eje del dataframe.

(Por ejemplo, el eje = 0 implica una operación a nivel de columnas con .apply (), que es un modo predeterminado, y el eje = 1 implicaría una operación a lo largo de las filas al tratar con objetos de dataframe puros)

Al usar aplicar a un grupo, he encontrado que .apply devolverá las columnas agrupadas. Hay una nota en la documentación (pandas.pydata.org/pandas-docs/stable/groupby.html):

“… Por lo tanto, las columnas agrupadas pueden incluirse en la salida, así como establecer los índices”.

.aggregate no devolverá las columnas agrupadas.