Pandas groupby 重新采样性能不佳

Jok*_*kab 6 python pandas pandas-groupby

我的问题

我在与 groupby 结合使用 resample 函数时遇到了问题。我正在做的操作目前在 5000 行的数据样本上需要 8 秒以上的时间,这对于我的要求是完全不合理的。

样本数据(500 行)

Pastebin 以数据为字典:https : //pastebin.com/RPNdhXsy


逻辑

我有一个季度间隔的日期数据,我想按列分组,然后每月重新采样组内的日期。

Input:
     isin  report_date   val
    SE001   2018-12-31     1
    SE001   2018-09-30     2
    SE001   2018-06-31     3
    US001   2018-10-31     4
    US001   2018-07-31     5

Output:
    isin   report_date      val        
    SE001   2018-12-31        1
            2018-11-30      NaN
            2018-10-31      NaN
            2018-09-30        2
            2018-08-31      NaN
            2018-07-31      NaN
            2018-06-30        3
    US001   2018-10-30        4    
            2018-09-31      NaN
            2018-08-31      NaN
            2018-07-31        5
Run Code Online (Sandbox Code Playgroud)

我曾经有过这样的操作:

df.groupby('isin').resample('M', on="report_date").first()[::-1]
Run Code Online (Sandbox Code Playgroud)

由于它的asfreq()性能似乎比使用on=in略好resample,因此我目前执行以下操作。不过还是很慢。我反转,因为resample似乎非可选地对日期进行降序排序。

df.set_index('report_date').groupby('isin').resample('M').asfreq()[::-1]
Run Code Online (Sandbox Code Playgroud)

如上所述,5000 行和大约 16 列这需要 15 秒才能运行,因为我需要在两个单独的数据帧上进行。使用 pastebin 中的示例数据(500 行),操作需要 0.7 秒,这对我来说太长了,因为我的最终数据将有 80 万行。

编辑:不同操作的时间

当前方式

setindex --- 0.001055002212524414 seconds ---
groupby --- 0.00033092498779296875 seconds ---
resample --- 0.004662036895751953 seconds ---
asfreq --- 0.8990700244903564 seconds ---
[::-1] --- 0.0013098716735839844 seconds ---
= 0.9056s
Run Code Online (Sandbox Code Playgroud)

老办法

groupby --- 0.0005779266357421875 seconds ---
resample --- 0.0044629573822021484 seconds ---
first --- 1.6829369068145752 seconds ---
[::-1] --- 0.001600027084350586 seconds ---
= 1.6894s
Run Code Online (Sandbox Code Playgroud)

由此看来,从 thepandas.core.resample.DatetimeIndexResamplerGroupby转换为 df似乎需要很长时间。怎么办?

EDIT2:使用重新索引

df.set_index('report_date').groupby('isin').apply(lambda x: x.reindex(pd.date_range(x.index.min(), x.index.max(), freq='M'), fill_value=0))[::-1]
Run Code Online (Sandbox Code Playgroud)

这需要 0.28 秒,这是一个巨大的改进。不过还是不太好。


我怎样才能加快速度?有没有另一种方法可以做同样的事情?

Mar*_*ang 1

我还注意到 groupby 上的重采样可能会很慢。就我而言,我使用数据重塑来加快速度,

df.set_index(['isin', 'report_date'])['val'].unstack(0).resample('M')
Run Code Online (Sandbox Code Playgroud)