Python Pandas groupby 应用 lambda 参数

Posted

技术标签:

【中文标题】Python Pandas groupby 应用 lambda 参数【英文标题】:Python Pandas groupby apply lambda arguments 【发布时间】:2018-05-13 01:43:08 【问题描述】:

在有关 Python Pandas groupby 的课程视频中(在 Python 中的数据科学简介课程中)给出了以下示例:

df.groupby('Category').apply(lambda df,a,b: sum(df[a] * df[b]), 'Weight (oz.)', 'Quantity')

其中 df 是一个 DataFrame,并且 lambda 用于计算两列的总和。 如果我理解正确,调用 apply 函数的 groupby 对象(由 groupby 返回)是一系列元组,由分组的索引和作为特定分组的 DataFrame 部分组成。

我不明白的是 lambda 的使用方式:

指定了三个参数(lambda df,a,b),但只有两个被显式传递('Weight (oz.)' 和 'Quantity')。解释器如何知道参数 'a' 和 'b' 是指定为参数的参数,而 df 是“按原样”使用的?

我查看了文档,但找不到这样一个具体示例的明确答案。我认为这与 df 在范围内有关,但找不到支持和详细说明该想法的信息。

【问题讨论】:

df.groupby('Category') 这个 groupby 对象本身就是你使用 apply 时的第一个参数。 谢谢,这为我指明了正确的方向。虽然看起来并不完全准确 【参考方案1】:

apply 方法本身将 groupby 对象的每个“组”作为第一个参数传递给函数。所以它知道根据位置将“重量”和“数量”与ab 相关联。 (例如,如果您计算第一个“组”参数,它们是第二个和第三个参数。

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

所以 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 是隐式将每个组作为第一个参数传递给函数参数。

来自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' 作为 附加 参数传递给 lambda 函数的每个调用

因此 apply 会遍历其中的每一个并执行您的 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

【讨论】:

以上是关于Python Pandas groupby 应用 lambda 参数的主要内容,如果未能解决你的问题,请参考以下文章

Python pandas:我们可以避免在 groupby/apply 这种情况下应用吗?

应用自定义 groupby 聚合函数在 pandas python 中输出二进制结果

Pandas groupby 使用两次应用时会复制组

Python、Pandas:GroupBy 属性文档

python [groupby]示例groupby #pandas #secret

[Python Cookbook] Pandas Groupby