【问题标题】:Clarification on lambda operator in pandas groupby关于 pandas groupby 中 lambda 运算符的说明
【发布时间】:2018-01-27 19:14:45
【问题描述】:

我无法发表评论,因为我是 stackoverflow 的新手,所以不能直接在线程中提问,但我想在 question 中澄清解决方案:

# 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 分组)。

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

【问题讨论】:

    标签: python pandas lambda


    【解决方案1】:

    这是state_office DataFrame:

    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
    

    如果您在 level=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 与自定义函数一起使用时,这些组将成为此函数的输入(x 在 lambda 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 在这一点上发现,如果形状不相同但有一个共同的轴,那么操作应该基于它来完成(更基本的是,如果你传递三个数字而不是元素方式除法,但由于您只传递一个数字,它知道您想将这三个数字中的每一个除以这个数字)。

    【讨论】:

    • 明白 -- 非常感谢您提供的详细信息,非常感谢!
    • @jbachlombardo 很高兴为您提供帮助。 :)
    【解决方案2】:

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

    GroupBy.apply(func, *args, **kwargs)[source] 应用函数 func 分组并将结果组合在一起。

    从上面的签名查看func

    函数:函数

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

    在 OP 的示例中,lambda x: 100 * x / float(x.sum() 在文档中是 func。从文档中,x 这里是一个数据框,groupby 调用之后的一组组。

    【讨论】:

      猜你喜欢
      • 2012-04-01
      • 2019-05-14
      • 2013-06-15
      • 1970-01-01
      • 1970-01-01
      • 2012-09-17
      • 1970-01-01
      • 2023-03-23
      • 1970-01-01
      相关资源
      最近更新 更多