多くの積み重ねられた時系列で構成されるDataFrameがあります。インデックスは(poolId、month)で、どちらも整数です。「月」は2000年以降の月数です。複数の変数の1か月遅れのバージョンを計算する最良の方法は何ですか?
今、私は次のようなことをします:
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コードと同等のdata.table呼び出しから変換しています:
dt.shift <- dt[, list(bal=myshift(bal), ...), by=list(poolId)]
実行には9秒しかかかりません。(ここでの「myshift」は「function(x)c(x [-1]、NA)」のようなものです。)
パンダのベライゾンをスピード的に戻す方法はありますか?これを0.8.1でテストしました。
編集:これは、十分に近いデータセットを生成する例です。これにより、私が何を意味するのかを理解できます。
ids = np.arange(48000)
lens = np.maximum(np.round(15+9.5*np.random.randn(48000)), 1.0).astype(int)
id_vec = np.repeat(ids, lens)
lens_shift = np.concatenate(([0], lens[:-1]))
mon_vec = np.arange(lens.sum()) - np.repeat(np.cumsum(lens_shift), lens)
n = len(mon_vec)
df = pd.DataFrame.from_items([('pool', id_vec), ('month', mon_vec)] + [(c, np.random.rand(n)) for c in 'abcde'])
df = df.set_index(['pool', 'month'])
%time df_shift = df.groupby(level=0).transform(lambda x: x.shift(-1))
試してみると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])