Mam DataFrame, która składa się z wielu zestawionych szeregów czasowych. Indeks to (poolId, month), gdzie obie są liczbami całkowitymi, a "miesiąc" jest liczbą miesięcy od 2000 roku. Jaki jest najlepszy sposób obliczania trzymiesięcznych opóźnionych wersji wielu zmiennych?Najbardziej efektywny sposób na zmianę szeregu czasowego MultiIndex
Teraz robię coś takiego:
cols_to_shift = ["bal", ...5 more columns...]
df_shift = df[cols_to_shift].groupby(level=0).transform(lambda x: x.shift(-1))
na przetwarzanie moich danych, to zajęło mi pełne 60 s do uruchomienia. (Mam 48K różne pule i łącznie 718k rzędach.)
mi przekształcenie to z kodu R i równoważnej data.table połączenia:
dt.shift <- dt[, list(bal=myshift(bal), ...), by=list(poolId)]
zajmuje tylko 9S uruchomić. (Tutaj "myshift" jest czymś w rodzaju "funkcji (x) c (x [-1], NA)").
Czy istnieje sposób, w jaki mogę uzyskać pandas Verison, aby wrócić do linii prędkości? Testowałem to na 0.8.1.
Edycja: Oto przykład generować wystarczająco ścisły-zestaw danych, dzięki czemu można uzyskać pewne wyobrażenie o tym, co to znaczy:
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))
To trwało 64 s, gdy próbowałem go. Te dane mają wszystkie serie zaczynające się od miesiąca 0; Naprawdę, powinny zakończyć się na miesiąc np.max (obiektyw), z niewyrównanymi datami rozpoczęcia, ale wystarczająco dobre.
Edycja 2: Oto niektóre porównanie kodu R. Zajmuje to 0,8 s. Współczynnik 80, niedobry.
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])
otworzyłem GitHub problem tutaj: https://github.com/pydata/pandas/issues/2162. Przyjrzę się –