groupby之后采用更快的方式来累加总和?

时间:2019-07-03 13:45:04

标签: python pandas pandas-groupby rolling-computation

给定一个数据框,其中每行对应于一定间隔的回报,我试图获得每天n分钟的正向股票回报。

我已经尝试过使用dask并对每个组的滚动计算进行多线程处理,但这似乎是我可以找出的最快方法。但是,对于大型数据框(数百万行)(252天和1000支股票),此步骤最多需要40分钟。

ret_df.sort_values(['date','time','stock'], ascending=False, inplace=True)
gb = ret_df.groupby(['date','stock'])
forward_sum_df = gb.rolling(4, on='time', min_periods = 0)['interval_return'].sum().reset_index()

这将按预期返回数据帧中每一行的下4次总和(按日期和库存),但是这样做非常缓慢。感谢您的帮助!

编辑:添加了示例以澄清

          date    stock            time      interval_ret
0   2017-01-03  10000001    09:30:00.000000   0.001418
1   2017-01-03  10000001    09:40:00.000000   0.000000
2   2017-01-03  10000001    09:50:00.000000   0.000000
3   2017-01-03  10000001    10:00:00.000000  -0.000474
4   2017-01-03  10000001    10:10:00.000000  -0.001417
5   2017-01-03  10000001    10:20:00.000000  -0.000944
6   2017-01-03  10000001    10:30:00.000000   0.000000
7   2017-01-03  10000001    10:40:00.000000   0.000000
8   2017-01-03  10000001    10:50:00.000000   0.000000
9   2017-01-03  10000001    11:00:00.000000  -0.000472

以此类推,例如库存10000002 ...和日期为2017-01-04 ....

例如,如果我的持有期限为30分钟而不是10分钟,我想总结3行“ interval_ret”,按日期和库存分组。例如:

        date      stock            time           interval_ret_30
0   2017-01-03  10000001    09:30:00.000000   0.001418
1   2017-01-03  10000001    09:40:00.000000   0.000000 - 0.000474
2   2017-01-03  10000001    09:50:00.000000   0.000000 - 0.000474 - 0.001417
3   2017-01-03  10000001    10:00:00.000000  -0.000474 - 0.001417 - 0.000944
4   2017-01-03  10000001    10:10:00.000000  -0.001417 - 0.000944
5   2017-01-03  10000001    10:20:00.000000  -0.000944
6   2017-01-03  10000001    10:30:00.000000   0.000000
7   2017-01-03  10000001    10:40:00.000000  -0.000472
8   2017-01-03  10000001    10:50:00.000000  -0.000472
9   2017-01-03  10000001    11:00:00.000000  -0.000472

1 个答案:

答案 0 :(得分:0)

我不知道您是否可以使它适应大熊猫,但是您可以使用numpy在不到一秒钟的时间内获得2000万个值的累积累计金额:

N         = 20000000
stocks    = (np.random.random(N)*100)
window    = 4
cumStocks = np.cumsum(np.append(stocks,np.zeros(window)))
rollSum   = cumStocks[window:] - cumStocks[:-window]

诀窍是计算整个数组的累加和,然后从自身减去与窗口大小相对应的偏移量得到的数组。

cumsum源数组用零填充以保持原始大小。比窗口大小更接近数组末尾的最后几个元素将仅获得剩余值的滚动总和。如果不需要这些“不完整”的总和,则只需使用cumStocks = np.cumsum(stocks),该计算就能在一秒钟内完成1亿个值。

有人似乎在这里使用熊猫找到了解决方案:https://stackoverflow.com/a/56886389/5237560

df.groupby(level=0).cumsum() - df.groupby(level=0).cumsum().shift(5)