Possiedo un DataFrame costituito da molte serie temporali sovrapposte. L'indice è (poolId, month) dove entrambi sono numeri interi, il "mese" è il numero di mesi dal 2000. Qual è il modo migliore per calcolare versioni ritardate di un mese di più variabili?Il modo più efficace per spostare le serie temporali MultiIndex
In questo momento, mi fare qualcosa di simile:
cols_to_shift = ["bal", ...5 more columns...]
df_shift = df[cols_to_shift].groupby(level=0).transform(lambda x: x.shift(-1))
Per i miei dati, questo mi ha portato un pieno 60 s per l'esecuzione. (Ho 48k piscine differenti per un totale di 718k righe.)
sto convertendo questo dal codice R e la chiamata data.table equivalente:
dt.shift <- dt[, list(bal=myshift(bal), ...), by=list(poolId)]
richiede solo 9 s per l'esecuzione. (Qui "myshift" è qualcosa di simile a "function (x) c (x [-1], NA)".)
C'è un modo per far sì che la versione di panda sia di nuovo in linea? Ho provato questo su 0.8.1.
Edit: Ecco un esempio di generare una serie di dati Close-sufficiente, in modo da poter avere un'idea di ciò che intendo:
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))
che ha avuto 64 s quando l'ho provato. Questi dati hanno tutte le serie a partire dal mese 0; in realtà, dovrebbero finire tutti al mese np.max (obiettivo), con date di inizio irregolari, ma abbastanza buone.
Modifica 2: ecco qualche codice R di confronto. Questo richiede 0,8 s. Fattore di 80, non va bene.
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])
ho aperto un problema GitHub qui: https://github.com/pydata/pandas/temi/2162. Dare un'occhiata –