2014-11-08 2 views
2

관심 변수가 Buy/Sell 인 거래자 데이터 집합이 있고 이진수이고 거래가 구매자 였고 1은 if 그것은 팔린다. 다음 예는 같습니다사용자 정의 groupby 집계 함수를 적용하여 pandas python의 이진 결과 출력

Trader  Buy/Sell 
    A   1 
    A   0 
    B   1 
    B   1 
    B   0 
    C   1 
    C   0 
    C   0 
나는 각 상인의 순 Buy/Sell을 계산하려는

상인이 구매와 같은 거래의 50 % 이상이 있다면, 그 경우 Buy/Sell 1의 것 그런 그가 50 % 미만으로 구입했을 경우 Buy/Sell이 0이고 정확히 50 %이면 NA가됩니다 (향후 계산시 무시됩니다).

따라서 상인 A에 대한 구매 비중은 NA를 제공하는 (매수)/(총 상인 수) = 1/2 = 0.5입니다. 상인 B 용

그것은 2/3 =은 1/3 = 0.33이 같아야 0

표 준다 상인 C 들면 1

제공 0.67 :

Trader  Buy/Sell 
    A   NA 
    B   1 
    C   0 

궁극적으로이 경우 1 인 구매 총 합계 수와이 경우 2 인 총 거래 수 (NA 무시)를 계산하고자합니다. 두 번째 표에는 관심이 없습니다. 나는 단지 집계 된 구매 건수와 집계 된 tota에 관심이있다. 카운트는 Buy/Sell입니다.

팬더에서 어떻게하면됩니까?

답변

7
import numpy as np 
import pandas as pd 

df = pd.DataFrame({'Buy/Sell': [1, 0, 1, 1, 0, 1, 0, 0], 
        'Trader': ['A', 'A', 'B', 'B', 'B', 'C', 'C', 'C']}) 

grouped = df.groupby(['Trader']) 
result = grouped['Buy/Sell'].agg(['sum', 'count']) 
means = grouped['Buy/Sell'].mean() 
result['Buy/Sell'] = np.select(condlist=[means>0.5, means<0.5], choicelist=[1, 0], 
    default=np.nan) 
print(result) 

내 원래의 대답은 사용자 정의 애그리 게이터 (aggregator), categorize 사용

 Buy/Sell sum count 
Trader      
A   NaN 1  2 
B    1 2  3 
C    0 1  3 

산출 : 사용자 정의 함수를 호출하는 것이 편리 할 수 ​​있지만

def categorize(x): 
    m = x.mean() 
    return 1 if m > 0.5 else 0 if m < 0.5 else np.nan 
result = df.groupby(['Trader'])['Buy/Sell'].agg([categorize, 'sum', 'count']) 
result = result.rename(columns={'categorize' : 'Buy/Sell'}) 

을 성능이 종종 상당히 느리다 내장 된 012와 비교하여 사용자 지정 함수를 사용할 때애그리 게이터 (예 : groupby/agg/mean). 빌트인 애그리 게이터 (built-in aggregators)는 Cython으로되어 있으며, 커스텀 기능은 성능을 일반 파이썬 for-loop 속도로 줄입니다.

그룹의 수가 일 때 속도의 차이가 특히 현저합니다. 예를 들어, 1,000 기와 10000 행 DataFrame와

import numpy as np 
import pandas as pd 
np.random.seed(2017) 
N = 10000 
df = pd.DataFrame({ 
    'Buy/Sell': np.random.randint(2, size=N), 
    'Trader': np.random.randint(1000, size=N)}) 

def using_select(df): 
    grouped = df.groupby(['Trader']) 
    result = grouped['Buy/Sell'].agg(['sum', 'count']) 
    means = grouped['Buy/Sell'].mean() 
    result['Buy/Sell'] = np.select(condlist=[means>0.5, means<0.5], choicelist=[1, 0], 
     default=np.nan) 
    return result 

def categorize(x): 
    m = x.mean() 
    return 1 if m > 0.5 else 0 if m < 0.5 else np.nan 

def using_custom_function(df): 
    result = df.groupby(['Trader'])['Buy/Sell'].agg([categorize, 'sum', 'count']) 
    result = result.rename(columns={'categorize' : 'Buy/Sell'}) 
    return result 

using_select 끝났 50X보다 빠른 using_custom_function :

In [69]: %timeit using_custom_function(df) 
10 loops, best of 3: 132 ms per loop 

In [70]: %timeit using_select(df) 
100 loops, best of 3: 2.46 ms per loop 

In [71]: 132/2.46 
Out[71]: 53.65853658536585