Python pandas:GroupBy.pipe()与apply()的比较

Python pandas:GroupBy.pipe()与apply()的比较,python,python-3.x,pandas,pandas-groupby,Python,Python 3.x,Pandas,Pandas Groupby,在关于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(['

在关于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

对于DataFrame对象,我可以看到
管道
功能与
应用
的不同之处,但对于GroupBy对象则没有。是否有人解释或举例说明了对于GroupBy,可以使用
pipe
而不是
apply
来做什么?

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
注:

以及:


示例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
s.groupby(df.A).sum()

A
X    0.5
Y    0.5
Name: B, dtype: float64
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