关于熊猫分组中lambda运算符的说明



我无法发表评论,因为我是堆栈溢出的新手,所以不能直接在线程中询问,但我想澄清这个问题的解决方案:

# From Paul H
import numpy as np
import pandas as pd
np.random.seed(0)
df = pd.DataFrame({'state': ['CA', 'WA', 'CO', 'AZ'] * 3,
'office_id': list(range(1, 7)) * 2,
'sales': [np.random.randint(100000, 999999)
for _ in range(12)]})
state_office = df.groupby(['state', 'office_id']).agg({'sales': 'sum'})
# Change: groupby state_office and divide by sum
state_pcts = state_office.groupby(level=0).apply(lambda x:
100 * x / float(x.sum()))

我了解多索引选择(级别 0 与级别 1),但我不清楚 lambda 函数中的每个x指的是什么。对我来说,x.sum()中的x是指level = 0(将每个分组中的所有结果相加level = 0),但100 * x中的x似乎是指 groupby 对象中的每个单独结果(而不是分组level = 0索引)。

很抱歉这样一个基本问题,但解释会非常有用!

这是数据帧state_office

state_office
Out: 
sales
state office_id        
AZ    2          589661
4          339834
6          201054
CA    1          760950
3          935865
5          464993
CO    1          737207
3          154900
5          277555
WA    2          510215
4          640508
6          557411

如果将其分组在级别=0,则组将是:

sales
state office_id        
AZ    2          589661
4          339834
6          201054

sales
state office_id        
CA    1          760950
3          935865
5          464993

sales
state office_id        
CO    1          737207
3          154900
5          277555

当您将 groupby.apply 与自定义函数一起使用时,这些组将成为此函数的输入(在 lambda x 中x)。我将使用术语group而不是 x 来更明确。

让你感到困惑的事情叫做广播。如果您使用group / group.sum()的特定组,那么它将把该组中的每个元素除以总和。让我们以第一组为例:

sales
state office_id        
AZ    2          589661
4          339834
6          201054

group.sum()回报:

group.sum()
Out: 
sales    1130549
dtype: int64

由于它只有一个元素,float(x.sum())将返回 1130549.0。(更简洁的版本是在 GroupBy 对象上选择销售系列,然后应用该函数。state_office.groupby(level=0)['sales'].apply(lambda x: 100 * x / x.sum())在这里,x是一个系列,所以x.sum()将是一个标量,所以你不需要float(x.sum()))。

如果将每个元素除以此值,则会得到所需的结果:

group / group.sum()
Out: 
sales
state office_id          
AZ    2          0.521570
4          0.300592
6          0.177837

此时的 Pandas/NumPy 发现,如果形状不相同但有一个共同的轴,则应基于此进行操作(更基本的是,如果您传递三个数字,则它将执行逐元素除法,但由于您只传递一个数字,它知道您要将这三个数字中的每一个除以这个数字)。

让我们一起阅读文档。(来源)

GroupBy.apply(func, *args, **kwargs)[source] Apply functionfunc按组划分并将结果组合在一起。

从上面的签名中查看func

函数 : 函数

一个可调用对象,它将数据帧作为其第一个参数,并返回 数据帧、序列或标量。此外,可赎回的可能需要 位置和关键字参数

在 OP 的示例中,文档中funclambda x: 100 * x / float(x.sum()。从文档中,x此处是一个数据帧,即groupby调用后的一组组。

最新更新