Python Pandas groupby(Pythonコースの紹介))のコースラビデオでは、次の例は与えられた:
df.groupby('Category').apply(lambda df,a,b: sum(df[a] * df[b]), 'Weight (oz.)', 'Quantity')
ここで、dfはDataFrameであり、ラムダは2つの列の合計を計算するために適用されます。私が正しく理解している場合、適用関数が呼び出されるgroupbyオブジェクト(groupbyによって返される)は、グループ化されたインデックスと、その特定のグループ化であるDataFrameの一部で構成される一連のタプルです。
私が理解していないのはラムダの使い方です:
3つの引数が指定されています(lambda df、a、b)が、明示的に渡されるのは2つだけです( 'Weight(oz。)'および 'Quantity')。インタプリタは、引数「a」と「b」が引数として指定されたものであり、dfが「そのまま」使用されていることをどのようにして知るのですか?
私はドキュメントを調べましたが、そのような特定の例の決定的な答えは見つかりませんでした。これはdfのスコープ内で何かを行う必要があると思いますが、サポートする情報やその考えの詳細を見つけることができません。
Applyメソッド自体は、関数の最初の引数としてgroupbyオブジェクトの各「グループ」を渡します。そのため、位置に基づいて「重量」と「数量」をa
とb
に関連付けることがわかっています。 (たとえば、最初の「グループ」引数を数える場合、これらは2番目と3番目の引数です。
df = pd.DataFrame(np.random.randint(0,11,(10,3)), columns = ['num1','num2','num3'])
df['category'] = ['a','a','a','b','b','b','b','c','c','c']
df = df[['category','num1','num2','num3']]
df
category num1 num2 num3
0 a 2 5 2
1 a 5 5 2
2 a 7 3 4
3 b 10 9 1
4 b 4 7 6
5 b 0 5 2
6 b 7 7 5
7 c 2 2 1
8 c 4 3 2
9 c 1 4 6
gb = df.groupby('category')
暗黙の引数はそれぞれ「グループ」、またはこの場合は各カテゴリです
gb.apply(lambda grp: grp.sum())
"grp"はラムダ関数の最初の引数であり、これまでのように何も指定する必要はありません。自動的にgroupbyオブジェクトの各グループと見なされます。
category num1 num2 num3
category
a aaa 14 13 8
b bbbb 21 28 14
c ccc 7 9 9
したがって、applyはこれらのそれぞれを通過し、合計操作を実行します
print(gb.groups)
{'a': Int64Index([0, 1, 2], dtype='int64'), 'b': Int64Index([3, 4, 5, 6], dtype='int64'), 'c': Int64Index([7, 8, 9], dtype='int64')}
print('1st GROUP:\n', df.loc[gb.groups['a']])
1st GROUP:
category num1 num2 num3
0 a 2 5 2
1 a 5 5 2
2 a 7 3 4
print('SUM of 1st group:\n', df.loc[gb.groups['a']].sum())
SUM of 1st group:
category aaa
num1 14
num2 13
num3 8
dtype: object
これが前の操作の最初の行と同じであることに注意してください
したがって、applyはimplicitly各グループを最初の引数として関数の引数に渡します。
docs から
GroupBy.apply(func、* args、** kwargs)
args、kwargs:タプルとディクテーション
Funcに渡すオプションの位置引数とキーワード引数
"* args"で渡された追加の引数は、暗黙のグループ引数の後に後に渡されます。
あなたのコードを使用して
gb.apply(lambda df,a,b: sum(df[a] * df[b]), 'num1', 'num2')
category
a 56
b 167
c 20
dtype: int64
ここで 'num1'および 'num2'は、ラムダ関数の各呼び出しにadditional引数として渡されています
したがって、applyはこれらのそれぞれを通過し、ラムダ演算を実行します
# copy and paste your lambda function
fun = lambda df,a,b: sum(df[a] * df[b])
print(gb.groups)
{'a': Int64Index([0, 1, 2], dtype='int64'), 'b': Int64Index([3, 4, 5, 6], dtype='int64'), 'c': Int64Index([7, 8, 9], dtype='int64')}
print('1st GROUP:\n', df.loc[gb.groups['a']])
1st GROUP:
category num1 num2 num3
0 a 2 5 2
1 a 5 5 2
2 a 7 3 4
print('Output of 1st group for function "fun":\n',
fun(df.loc[gb.groups['a']], 'num1','num2'))
Output of 1st group for function "fun":
56