Tôi có một DataFrame bao gồm nhiều chuỗi thời gian xếp chồng. Chỉ số là (poolId, tháng) trong đó cả hai là số nguyên, "tháng" là số tháng kể từ năm 2000. Cách tốt nhất để tính các phiên bản một tháng bị trễ của nhiều biến là gì?Cách hiệu quả nhất để thay đổi chuỗi thời gian MultiIndex
Ngay bây giờ, tôi làm điều gì đó như:
cols_to_shift = ["bal", ...5 more columns...]
df_shift = df[cols_to_shift].groupby(level=0).transform(lambda x: x.shift(-1))
Đối với dữ liệu của tôi, điều này đã cho tôi một đầy đủ 60 s để chạy. (Tôi có 48k hồ khác nhau và có tổng cộng 718k hàng.)
tôi là chuyển đổi này từ mã R và cuộc gọi data.table tương đương:
dt.shift <- dt[, list(bal=myshift(bal), ...), by=list(poolId)]
chỉ mất 9 s để chạy. (Ở đây "myshift" là một cái gì đó giống như "chức năng (x) c (x [-1], NA)".)
Có cách nào tôi có thể đưa chú gấu trúc trở lại tốc độ không? Tôi đã thử nghiệm điều này trên 0.8.1.
Edit: Đây là một ví dụ về việc tạo ra một tập dữ liệu gần đủ, vì vậy bạn có thể nhận được một số ý tưởng về những gì tôi có nghĩa là:
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))
Đó mất 64 s khi tôi thử nó. Dữ liệu này có mọi chuỗi bắt đầu từ tháng 0; thực sự, tất cả chúng sẽ kết thúc vào tháng np.max (ống kính), với ngày bắt đầu bị rách nát, nhưng đủ tốt.
Chỉnh sửa 2: Dưới đây là một số mã so sánh R. Điều này mất 0.8 s. Yếu tố 80, không tốt.
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])
Tôi mở một vấn đề GitHub ở đây: https://github.com/pydata/pandas/issue/2162. Tôi sẽ xem xét –