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

2024-04-19 04:04:34 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个交易者交易的数据集,其中的利息变量是Buy/Sell,它是二进制的,值为1,如果交易是买入,则为0。示例如下:

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来说,买入比例是(买入数量)/(交易者总数)=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,总的交易数量(不考虑NAs)在本例中是2。我对第二个表不感兴趣,我只感兴趣的是购买的总数量和Buy/Sell的总数量。

我怎样才能在熊猫身上做到这一点?


Tags: 数据示例数量交易者二进制buy交易中将
1条回答
网友
1楼 · 发布于 2024-04-19 04:04:34
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)

收益率

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

我最初的答案是使用自定义聚合器,categorize

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 循环速度。

当组数为 很大。例如,对于包含1000个组的10000行数据帧

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_selectusing_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

相关问题 更多 >