pandas groupby apply 的速度非常慢。

3
当我调用df.groupby([...]).apply(lambda x: ...)时,性能非常差。有没有更快/更直接的方法来执行这个简单的查询?
为了证明我的观点,这里是一些设置DataFrame的代码:
import pandas as pd

df = pd.DataFrame(data=
    {'ticker': ['AAPL','AAPL','AAPL','IBM','IBM','IBM'],
       'side': ['B','B','S','S','S','B'],
       'size': [100, 200, 300, 400, 100, 200],
      'price': [10.12, 10.13, 10.14, 20.3, 20.2, 20.1]})


    price   side     size   ticker
0   10.12   B        100    AAPL
1   10.13   B        200    AAPL
2   10.14   S        300    AAPL
3   20.30   S        400    IBM
4   20.20   S        100    IBM
5   20.10   B        200    IBM

现在有一个非常耗时的部分,我需要加速:

%timeit avgpx = df.groupby(['ticker','side']) \
.apply(lambda group: (group['size'] * group['price']).sum() / group['size'].sum())

3.23 ms ± 148 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)

这样做可以得到正确的结果,但正如您在上面看到的,需要很长时间(3.23毫秒似乎不算太多,但这只是6行... 当我在真实数据集上使用它时,它会花费很长时间)。

ticker  side
AAPL    B       10.126667
        S       10.140000
IBM     B       20.100000
        S       20.280000
dtype: float64

1
在进行代码优化之前,了解您的目标是什么将非常有帮助。 - cs95
我所尝试的就是计算每个股票/方向的平均价格。当我在数据框中使用大约40K行进行这个确切的操作时,性能非常慢(几秒钟)。我认为我可能只是使用lambda表达式做错了事情? - user5406764
1个回答

5

通过预先计算产品并且去掉apply,您可以节省一些时间。

df['scaled_size'] = df['size'] * df['price']
g = df.groupby(['ticker', 'side'])

g['scaled_size'].sum() / g['size'].sum()

ticker  side
AAPL    B       10.126667
        S       10.140000
IBM     B       20.100000
        S       20.280000
dtype: float64

100 loops, best of 3: 2.58 ms per loop

合理性检查

df.groupby(['ticker','side']).apply(
    lambda group: (group['size'] * group['price']).sum() / group['size'].sum())

ticker  side
AAPL    B       10.126667
        S       10.140000
IBM     B       20.100000
        S       20.280000
dtype: float64

100 loops, best of 3: 5.02 ms per loop

在我的计算机上,去掉apply似乎会使速度提高2倍。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接