Pandas 移动多索引时间序列的最有效方法

Pandas 移动多索引时间序列的最有效方法,pandas,Pandas,我有一个由许多堆叠的时间序列组成的数据帧。索引是(poolId,month),其中两者都是整数,“month”是自2000年以来的月数。计算多个变量滞后一个月版本的最佳方法是什么 现在,我做了一些类似的事情: cols_to_shift = ["bal", ...5 more columns...] df_shift = df[cols_to_shift].groupby(level=0).transform(lambda x: x.shift(-1)) 就我的数据而言,这花了我整整60秒的时

我有一个由许多堆叠的时间序列组成的数据帧。索引是(poolId,month),其中两者都是整数,“month”是自2000年以来的月数。计算多个变量滞后一个月版本的最佳方法是什么

现在,我做了一些类似的事情:

cols_to_shift = ["bal", ...5 more columns...]
df_shift = df[cols_to_shift].groupby(level=0).transform(lambda x: x.shift(-1))
就我的数据而言,这花了我整整60秒的时间。(我有48k个不同的池,总共有718k行。)

我正在从R代码和等效数据转换此值。表调用:

dt.shift <- dt[, list(bal=myshift(bal), ...), by=list(poolId)]
我试的时候花了64秒。此数据从第0个月开始具有每个系列;事实上,它们都应该在np.max(lens)月结束,开始日期参差不齐,但已经足够好了

编辑2:这里有一些比较R代码。这需要0.8秒。系数80,不好

library(data.table)
ids <- 1:48000
lens <- as.integer(pmax(1, round(rnorm(ids, mean=15, sd=9.5))))
id.vec <- rep(ids, times=lens)
lens.shift <- c(0, lens[-length(lens)])
mon.vec <- (1:sum(lens)) - rep(cumsum(lens.shift), times=lens)
n <- length(id.vec)
dt <- data.table(pool=id.vec, month=mon.vec, a=rnorm(n), b=rnorm(n), c=rnorm(n), d=rnorm(n), e=rnorm(n))
setkey(dt, pool, month)
myshift <- function(x) c(x[-1], NA)
system.time(dt.shift <- dt[, list(month=month, a=myshift(a), b=myshift(b), c=myshift(c), d=myshift(d), e=myshift(e)), by=pool])
库(data.table)

ids我建议您重新塑造数据,并与groupby方法相比进行一次转换:

result = df.unstack(0).shift(1).stack()
这将切换级别的顺序,以便您希望交换和重新排序:

result = result.swaplevel(0, 1).sortlevel(0)
您可以验证它是否延迟了一个周期(您想要的是班次(1)而不是班次(-1)):

此方法的性能还不错(在0.9.0中可能会慢一点):


我在此处打开了一个GitHub问题:。我来看看这是一个很大的进步!在0.8.1下,我用了6.6秒;希望下周我们能安装0.9.0,这样我就可以试试了。一个不同之处是,由于它在stack()上删除了由shift()生成的NaN项,所以它的行数比上一个少,但这在join()中得到了解决。(我的意思是移位(-1);这是一个危险率计算,所以是前瞻性的。)我所做的性能改进是在行李箱中。正在努力尽快发布新版本
result = result.swaplevel(0, 1).sortlevel(0)
In [17]: result.ix[1]
Out[17]: 
              a         b         c         d         e
month                                                  
1      0.752511  0.600825  0.328796  0.852869  0.306379
2      0.251120  0.871167  0.977606  0.509303  0.809407
3      0.198327  0.587066  0.778885  0.565666  0.172045
4      0.298184  0.853896  0.164485  0.169562  0.923817
5      0.703668  0.852304  0.030534  0.415467  0.663602
6      0.851866  0.629567  0.918303  0.205008  0.970033
7      0.758121  0.066677  0.433014  0.005454  0.338596
8      0.561382  0.968078  0.586736  0.817569  0.842106
9      0.246986  0.829720  0.522371  0.854840  0.887886
10     0.709550  0.591733  0.919168  0.568988  0.849380
11     0.997787  0.084709  0.664845  0.808106  0.872628
12     0.008661  0.449826  0.841896  0.307360  0.092581
13     0.727409  0.791167  0.518371  0.691875  0.095718
14     0.928342  0.247725  0.754204  0.468484  0.663773
15     0.934902  0.692837  0.367644  0.061359  0.381885
16     0.828492  0.026166  0.050765  0.524551  0.296122
17     0.589907  0.775721  0.061765  0.033213  0.793401
18     0.532189  0.678184  0.747391  0.199283  0.349949

In [18]: df.ix[1]
Out[18]: 
              a         b         c         d         e
month                                                  
0      0.752511  0.600825  0.328796  0.852869  0.306379
1      0.251120  0.871167  0.977606  0.509303  0.809407
2      0.198327  0.587066  0.778885  0.565666  0.172045
3      0.298184  0.853896  0.164485  0.169562  0.923817
4      0.703668  0.852304  0.030534  0.415467  0.663602
5      0.851866  0.629567  0.918303  0.205008  0.970033
6      0.758121  0.066677  0.433014  0.005454  0.338596
7      0.561382  0.968078  0.586736  0.817569  0.842106
8      0.246986  0.829720  0.522371  0.854840  0.887886
9      0.709550  0.591733  0.919168  0.568988  0.849380
10     0.997787  0.084709  0.664845  0.808106  0.872628
11     0.008661  0.449826  0.841896  0.307360  0.092581
12     0.727409  0.791167  0.518371  0.691875  0.095718
13     0.928342  0.247725  0.754204  0.468484  0.663773
14     0.934902  0.692837  0.367644  0.061359  0.381885
15     0.828492  0.026166  0.050765  0.524551  0.296122
16     0.589907  0.775721  0.061765  0.033213  0.793401
17     0.532189  0.678184  0.747391  0.199283  0.349949
In [19]: %time result = df.unstack(0).shift(1).stack()
CPU times: user 1.46 s, sys: 0.24 s, total: 1.70 s
Wall time: 1.71 s