2017-11-10 2 views
4

예를 들어 .pipe() GroupBy 개체에 대한 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 기능이 DataFrame 개체에 대한 apply 어떻게 다른지 볼 수 있지만 GROUPBY 개체 수 있습니다. 누구든지 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