2017-11-10 8 views
4

GroupByオブジェクトの新しい.pipe()メソッドに関するpandas documentationの例では、同じラムダを受け入れる.apply()メソッドは同じ結果を返します。pandas:GroupBy .pipe()vs .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機能は、データフレームのオブジェクトのためではなく、GROUPBYオブジェクトのapplyとどのように異なるかを見ることができます。誰でも、pipeでできることの説明や例はありますか?GroupByの場合はapplyではありませんか?

答えて

5

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
検討

セットアップが同じ量に1に全体'B'列合計を作ります。このためには、いくつのグループが存在するかを計算で把握する必要があります。これは、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