应用自定义groupby聚合函数在pandas python中输出二进制结果

前端之家收集整理的这篇文章主要介绍了应用自定义groupby聚合函数在pandas python中输出二进制结果前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我有一个交易者交易的数据集,其中感兴趣的变量是买入/卖出,它是二元的,并且在交易是买入时取值1,如果是卖出则取0.一个例子如下:
Trader     Buy/Sell
  A           1
  A           0
  B           1
  B           1
  B           0
  C           1
  C           0
  C           0

我想计算每个交易者的净买入/卖出,如果交易者有超过50%的交易作为买入,他将买入/卖出1,如果他买入少于50%那么他会买入/卖出0,如果它恰好是50%,他将有NA(并且在将来的计算中将被忽略).

因此对于交易员A,买入比例​​是(买入数量)/(交易者总数)= 1/2 = 0.5,这给出了NA.

对于交易者B,它是2/3 = 0.67,给出1

对于交易者C,它是1/3 = 0.33,给出0

该表应如下所示:

Trader     Buy/Sell
  A           NA
  B           1
  C           0

最终我想计算总的聚合购买数量,在这种情况下是1,以及聚合的交易总数(无视NA),在这种情况下是2.我对第二个表不感兴趣,我只是感兴趣在总购买数量和买/卖总数(总数)中.

我怎么能在pandas中做到这一点?

import numpy as np
import pandas as pd

df = pd.DataFrame({'Buy/Sell': [1,1,0],'Trader': ['A','A','B','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,default=np.nan)
print(result)

产量

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'})

虽然调用自定义函数可能很方便,但通常会有性能
与内置功能相比,使用自定义功能时速度明显变慢
聚合器(例如groupby / agg / mean).内置聚合器是
Cythonized,而自定义函数降低了普通Python的性能
for-loop速度.

当组数为时,速度的差异尤为显着
大.例如,对于具有1000个组的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,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,'count'])
    result = result.rename(columns={'categorize' : 'Buy/Sell'})
    return result

using_select比using_custom_function快50倍:

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

猜你在找的设计模式相关文章