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