【问题标题】:pandas: GroupBy .pipe() vs .apply()熊猫:GroupBy .pipe() 与 .apply()
【发布时间】:2018-04-23 21:31:24
【问题描述】:

pandas documentation 的示例中,关于 GroupBy 对象的新 .pipe() 方法,接受相同 lambda 的 .apply() 方法将返回相同的结果。

In [195]: import numpy as np

In [196]: n = 1000

In [197]: df = pd.DataFrame({'Store': np.random.choice(['Store_1', 'Store_2'], n),
   .....:                    'Product': np.random.choice(['Product_1', 'Product_2', 'Product_3'], n),
   .....:                    'Revenue': (np.random.random(n)*50+10).round(2),
   .....:                    'Quantity': np.random.randint(1, 10, size=n)})

In [199]: (df.groupby(['Store', 'Product'])
   .....:    .pipe(lambda grp: grp.Revenue.sum()/grp.Quantity.sum())
   .....:    .unstack().round(2))

Out[199]: 
Product  Product_1  Product_2  Product_3
Store                                   
Store_1       6.93       6.82       7.15
Store_2       6.69       6.64       6.77

我可以看到 pipe 功能与 apply 的 DataFrame 对象有何不同,但 GroupBy 对象却没有。有没有人解释或举例说明pipe 可以做什么,而apply 不能用于 GroupBy?

【问题讨论】:

    标签: python python-3.x pandas pandas-groupby


    【解决方案1】:

    pipe 所做的是允许您传递可调用对象,并期望调用 pipe 的对象是传递给可调用对象的对象。

    对于apply,我们假设调用apply 的对象具有子组件,每个子组件将传递给传递给apply 的可调用对象。在groupby 的上下文中,子组件是调用groupby 的数据帧的切片,其中每个切片本身就是一个数据帧。这与groupby 系列类似。

    您可以在groupby 上下文中使用pipe 所做的主要区别在于,您可以在groupby 对象的整个范围内使用可调用对象。对于申请,你只知道本地切片。

    设置
    考虑df

    df = pd.DataFrame(dict(
        A=list('XXXXYYYYYY'),
        B=range(10)
    ))
    
       A  B
    0  X  0
    1  X  1
    2  X  2
    3  X  3
    4  Y  4
    5  Y  5
    6  Y  6
    7  Y  7
    8  Y  8
    9  Y  9
    

    示例 1
    使整个'B' 列总和为1,而每个子组的总和为相同的数量。这要求计算知道存在多少组。这是我们无法用 apply 做的事情,因为 apply 不知道存在多少组。

    s = df.groupby('A').B.pipe(lambda g: df.B / g.transform('sum') / g.ngroups)
    s
    
    0    0.000000
    1    0.083333
    2    0.166667
    3    0.250000
    4    0.051282
    5    0.064103
    6    0.076923
    7    0.089744
    8    0.102564
    9    0.115385
    Name: B, dtype: float64
    

    注意:

    s.sum()
    
    0.99999999999999989
    

    还有:

    s.groupby(df.A).sum()
    
    A
    X    0.5
    Y    0.5
    Name: B, dtype: float64
    

    示例 2
    从另一组的值中减去一组的平均值。同样,apply 无法做到这一点,因为 apply 不知道其他组。

    df.groupby('A').B.pipe(
        lambda g: (
            g.get_group('X') - g.get_group('Y').mean()
        ).append(
            g.get_group('Y') - g.get_group('X').mean()
        )
    )
    
    0   -6.5
    1   -5.5
    2   -4.5
    3   -3.5
    4    2.5
    5    3.5
    6    4.5
    7    5.5
    8    6.5
    9    7.5
    Name: B, dtype: float64
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-07-16
      • 2019-02-28
      • 2022-07-05
      • 2022-12-16
      • 2017-11-17
      • 2019-02-24
      • 1970-01-01
      相关资源
      最近更新 更多