pandas GroupBy pipe vs apply

2024-04-25 13:34:37 发布

您现在位置:Python中文网/ 问答频道 /正文

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功能与DataFrame对象的apply有何不同,但不是GroupBy对象的apply。有没有人能解释或举例说明用pipe而不是用apply来处理GroupBy?


Tags: 对象方法storelambdaindataframedfnp
1条回答
网友
1楼 · 发布于 2024-04-25 13:34:37

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

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

使用groupby上下文中的pipe所能做的主要区别在于,您对groupby对象的整个可调用范围都是可用的。对于apply,您只知道本地切片。

设置 考虑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

相关问题 更多 >