应用自定义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'}) 虽然调用自定义函数可能很方便,但通常会有性能 当组数为时,速度的差异尤为显着 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 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |