Pandas .aggregate
関数と.apply
関数の違いを理解できません。
次の例を参考にしてください:データセットをロードし、groupby
を実行し、単純な関数を定義して、ユーザー.agg
または.apply
を定義します。
ご覧のとおり、関数内の印刷ステートメントは、.agg
および.apply
を使用した後も同じ出力になります。一方、結果は異なります。何故ですか?
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
apply
の使用:
by_species.apply(f)
#<class 'pandas.core.frame.DataFrame'>
# 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
#<class 'pandas.core.frame.DataFrame'>
# 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
#<class 'pandas.core.frame.DataFrame'>
# 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
#<class 'pandas.core.frame.DataFrame'>
# 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
agg
の使用
by_species.agg(f)
#<class 'pandas.core.frame.DataFrame'>
# 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
#<class 'pandas.core.frame.DataFrame'>
# 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
#<class 'pandas.core.frame.DataFrame'>
# 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
は、関数を各グループ(Species
)に適用します。関数は1を返すため、3つのグループのそれぞれに1つの値が返されます。
agg
aggregates each column(feature) for each group、つまり、最終的にグループごとの列ごとに1つの値になります。
groupby
のドキュメントを読んでください。非常に役に立ちます。また、ウェブ上に浮かんでいるたくさんのチュートリアルもあります。
(注:これらの比較はDataframeGroupbyオブジェクトに関連しています)
もっともらしい。apply()と比較した.agg()の利点、DataFrame GroupByオブジェクト:
1).agg()は、一度に複数の関数を適用する柔軟性を提供します、または各列に関数のリストを渡します。
2)また、データフレームの異なる列に異なる関数を一度に適用します。
つまり、各操作で各列をほぼ制御できます。
詳細については、次のリンクをご覧ください。 http://pandas.pydata.org/pandas-docs/version/0.13.1/groupby.html
ただし、関数の適用は、データフレームの各列に一度に1つの関数を適用するように制限できます。したがって、同じ列に対して異なる操作を呼び出すには、apply関数を繰り返し呼び出す必要がある場合があります。
ここに、DataframeGroupByオブジェクトの.apply()と.agg()の比較例があります:
まず、.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
次に、.agg()を使用して同じ操作を簡単に確認します:
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
<lambda> 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
そのため、.apply()と比較して、.agg()はDataFrameGroupByオブジェクトの処理に非常に便利です。しかし、純粋なデータフレームオブジェクトのみを処理し、DataFrameGroupByオブジェクトは処理しない場合、apply()はデータフレームの任意の軸に沿って関数を適用できるため、apply()は非常に役立ちます。
(例:軸= 0は、デフォルトのモードである.apply()、による列単位の演算を意味し、axis = 1は、純粋なデータフレームオブジェクトを処理する際の行単位の操作を意味します)
Groupbyへの適用を使用すると、.apply
がグループ化された列を返すことに気づきました。ドキュメントに注記があります( pandas.pydata.org/pandas-docs/stable/groupby.html ):
"...したがって、グループ化された列は、インデックスを設定するだけでなく、出力に含めることができます。"
.aggregate
はグループ化された列を返しません。
適用と集計の主な違いは次のとおりです。
apply()-
cannot be applied to multiple groups together
For apply() - We have to get_group()
ERROR : -iris.groupby('Species').apply({'Sepal.Length':['min','max'],'Sepal.Width':['mean','min']})# It will throw error
Work Fine:-iris.groupby('Species').get_group('Setosa').apply({'Sepal.Length':['min','max'],'Sepal.Width':['mean','min']})# It will throw error
#because functions are applied to one data frame
agg()-
can be applied to multiple groups together
For apply() - We do not have to get_group()
iris.groupby('Species').agg({'Sepal.Length':['min','max'],'Sepal.Width':['mean','min']})
iris.groupby('Species').get_group('versicolor').agg({'Sepal.Length':['min','max'],'Sepal.Width':['mean','min']})