在关于Python Pandas groupby的课程视频中(在Python课程的数据科学入门中),给出了以下示例:
df.groupby('Category').apply(lambda df,a,b: sum(df[a] * df[b]), 'Weight (oz.)', 'Quantity')
其中df是DataFrame,并且应用lambda来计算两列的总和。 如果我理解正确的话,groupby对象(由groupby返回)调用apply函数是一系列元组,由分组的索引和作为特定分组的DataFrame的一部分组成。
我不明白的是使用lambda的方式:
指定了三个参数(lambda df,a,b),但只有两个被明确传递(' Weight(oz。)'' Quantity')。口译员如何知道这些论点' a'和' b'是指定为参数的那些,并且使用df' as-is'?
我查看了文档,但找不到这样一个具体例子的明确答案。我认为这必须对df在范围内做些什么,但却无法找到支持和详细说明这种想法的信息。
答案 0 :(得分:6)
apply方法本身会传递每个"组" groupby对象作为函数的第一个参数。所以它知道将“权重”与“权重”联系起来。和"数量"基于排名,a
和b
。 (例如,如果算上第一个"组"参数,它们就是第二和第三个参数。
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"是lambda函数的第一个参数 请注意我不必为它指定任何内容,因为它已经被自动作为groupby对象的每个组
category num1 num2 num3
category
a aaa 14 13 8
b bbbb 21 28 14
c ccc 7 9 9
因此,申请将通过其中的每一项并执行求和操作
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
注意这与我们上一次操作的第一行是如何相同的
因此,应用隐式将每个组作为第一个参数传递给函数参数。
来自docs
GroupBy.apply(func,* args,** kwargs)
args,kwargs:tuple and dict
传递给func的可选位置和关键字参数
附加的Args传入" * 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'正在作为附加参数传递给lambda函数的每次调用
因此,申请将通过其中的每一项并执行您的lambda操作
# 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