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

标签 python pandas group-by aggregate-functions

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

Trader     Buy/Sell
  A           1
  A           0
  B           1
  B           1
  B           0
  C           1
  C           0
  C           0

我想计算每个交易者的净买入/卖出,如果交易者有超过 50% 的交易是买入,他将有一个买入/卖出 为 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,以及交易的总数(不考虑 NA)在本例中为 2。我对第二张表不感兴趣,我我只对购买的总数量和Buy/Sell 的总数量(计数)感兴趣。

我如何在 Pandas 中执行此操作?

最佳答案

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

当组数为 大的。例如,对于包含 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, 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

关于python - 应用自定义 groupby 聚合函数在 pandas python 中输出二进制结果,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26812763/

相关文章:

python - 无法在pycharm中安装BeautifulSoup

python - 使用 python SSH 和 telnet 到本地主机

python - python 如何处理 pandas 中凌乱的数据格式?

mysql - 如何对 Group by 的结果进行降序排序?

MYSQL 内连接错误 - 'm.account_no' 中的未知列 'where clause'

java - 将 JPA 与 Oracle 一起使用并按小时分组时出现问题

python - 如何在 Python 中使用 scipy.integrate.quad 中的参数 epsabs?

python - tflearn 创建多个模型

python - 如何根据 2 个数据框中的列匹配创建列表? Python

python / Pandas : how to read a csv in cp1252 with a first row to delete?