在Python中的自定义滚动时间间隔窗口上加速GroupBy sum函数?
我试图根据一个预先定义的时间间隔,如年(基本上是一个滚动的年度总和),根据多指标计算值的滚动总和。数据结构如下所示,其中索引有两个级别,rdate和pdate:在Python中的自定义滚动时间间隔窗口上加速GroupBy sum函数?,python,datetime,pandas,dataframe,Python,Datetime,Pandas,Dataframe,我试图根据一个预先定义的时间间隔,如年(基本上是一个滚动的年度总和),根据多指标计算值的滚动总和。数据结构如下所示,其中索引有两个级别,rdate和pdate: Value Desired Result Reference Published 2009-06-30 2009-07-31 745.000 745.000 2009-08-13 745.000 745.000 2009-09
Value Desired Result
Reference Published
2009-06-30 2009-07-31 745.000 745.000
2009-08-13 745.000 745.000
2009-09-30 2009-10-30 0.000 745.000
2009-12-31 2010-02-05 496.000 1241.000
2010-03-02 496.000 1241.000
2010-03-31 2010-04-30 80.000 1321.000
2010-06-30 2010-07-30 30.000 606.000
2010-09-30 2010-11-03 -110.000 496.000
2010-11-07 437.000 1043.000
2010-12-31 2011-02-04 440.000 1483.000
2011-03-31 2011-05-05 1031.000 1938.000
2011-06-30 2011-07-29 53.000 1961.000
2011-09-30 2011-11-04 2.000 1526.000
2011-12-31 2012-02-03 -191.000 895.000
我对pandas还不熟悉,所以我可能会错过一些简单的功能或优化,但以下是我的解决方案:
def sum_func(df):
tmp = []
df = df.to_frame()
for ((rdate, pdate),value) in df.itertuples():
t0 = rdate - pd.DateOffset(years=1,days=1)
tmp += [df.loc(axis=0)[t0:rdate,t0:pdate].groupby(level=0,axis=0).tail(1).sum(skipna=False)]
return pd.DataFrame(tmp, index=df.index)
然而,这似乎相当缓慢:
%timeit sum_func(test_df)
10 loops, best of 3: 49.2 ms per loop
我需要为更大的数据集运行数千次,所以我需要一个快速的解决方案。我已经安装了numexpr和瓶颈。索引和分组的时间占92.5%,因此我猜主要的优化将在那里进行:
%lprun -f sum_func sum_func(test_df)
Timer unit: 3.42123e-07 s
Total time: 0.0825231 s
File: <ipython-input-38-b6071946e5e0>
Function: sum_func at line 1
Line # Hits Time Per Hit % Time Line Contents
==============================================================
1 def sum_func(df):
2 1 5 5.0 0.0 tmp = []
3 1 1884 1884.0 0.8 df = df.to_frame()
4 21 965 46.0 0.4 for ((rdate, pdate),value) in df.itertuples():
5 20 10867 543.4 4.5 t0 = rdate - pd.DateOffset(years=1,days=1)
6 20 223104 11155.2 92.5 tmp += [df.loc(axis=0)[t0:rdate,t0:pdate].groupby(level=0,axis=0).tail(1).sum(skipna=False)]
7 1 4384 4384.0 1.8 return pd.DataFrame(tmp, index=df.index)
减少近25%:
%timeit stm(test_df)
10 loops, best of 3: 37.6 ms per loop
也许熊猫的索引速度更快?有什么帮助吗?谢谢我想这是个合适的地方。我试图演示您的方法,但每个方法都返回不同的输出-没有人想要输出。为什么?jezrael,日期和数值有数据问题。。现在应该可以用了。。对不起
%timeit stm(test_df)
10 loops, best of 3: 37.6 ms per loop