2015-01-16 13 views
7

Ho visto un sacco di post su come è possibile farlo con una stringa di data, ma sto provando qualcosa per una colonna di dataframe e non ho avuto fortuna finora. Il mio metodo attuale è: ottenere il giorno della settimana da 'myday' e quindi sfalsare per ottenere il lunedì.Ricevi la data di inizio della settimana (lunedì) da una colonna della data in Python (panda)?

df['myday'] is column of dates. 
mydays = pd.DatetimeIndex(df['myday']).weekday 
df['week_start'] = pd.DatetimeIndex(df['myday']) - pd.DateOffset(days=mydays) 

Ma ho TypeError: tipo non supportato per il componente giorni timedelta: numpy.ndarray

Come posso ottenere la data di inizio settimana da una colonna df?

risposta

1

non riesce perché pd.DateOffset si aspetta un singolo numero intero come parametro (e si sta alimentando un array). Puoi utilizzare DateOffset solo per modificare una colonna della data con lo stesso offset.

provare questo:

import datetime as dt 
# Change 'myday' to contains dates as datetime objects 
df['myday'] = pd.to_datetime(df['myday']) 
# 'daysoffset' will container the weekday, as integers 
df['daysoffset'] = df['myday'].apply(lambda x: x.weekday()) 
# We apply, row by row (axis=1) a timedelta operation 
df['week_start'] = df.apply(lambda x: x['myday'] - dt.TimeDelta(days=x['mydays']), axis=1) 

Non ho effettivamente testato questo codice, (non c'erano dati di esempio), ma che dovrebbe lavorare per quello che hai descritto.

Tuttavia, si potrebbe voler guardare pandas.Resample, che potrebbe fornire una soluzione migliore - a seconda esattamente quello che stai cercando.

+0

Grazie per la spiegazione. Questa soluzione fa esattamente quello che volevo! – dev28

11

Un'altra alternativa:

df['week_start'] = df['myday'].dt.to_period('W').apply(lambda r: r.start_time) 

Questo imposterà 'Inizio_settimana' di essere il primo Lunedi la prima volta nel 'MyDay'.

4

Mentre entrambe le soluzioni di cui sopra funzionano tendono a cercare di evitare l'utilizzo di apply in Pandas perché di solito è piuttosto lento rispetto ai metodi basati su array. Per evitare questo, possiamo modificare il metodo basato sui giorni feriali e lanciare semplicemente il giorno della settimana come numpy timedelta64[D].

df['myday'] - df['myday'].dt.weekday.astype('timedelta64[D]') 

Utilizzando i miei dati di test con 60.000 datetimes ho ottenuto le seguenti volte con le altre due risposte suggerite e il metodo basato casting.

%timeit df.apply(lambda x: x['myday'] - datetime.timedelta(days=x['myday'].weekday()), axis=1) 
>>> 1 loop, best of 3: 7.43 s per loop 
%timeit df['myday'].dt.to_period('W').apply(lambda r: r.start_time) 
>>> 1 loop, best of 3: 2.38 s per loop 
%timeit df['myday'] - df['myday'].dt.weekday.astype('timedelta64[D]') 
>>> 100 loops, best of 3: 12.3 ms per loop 

o quasi 200 volte più veloce sul mio set di dati.

+0

Come funziona? df ['myday']. dt.weekday.astype ('timedelta64 [D]') nel mio dataset restituisce una serie di tutti gli zeri. Perché o come sarebbe sottratto 0 da df ['myday'] al lavoro? Questa sembra la soluzione migliore. –

+0

Chiarire il post di cui sopra, il modo in cui ho capito cosa sta succedendo è che in pratica si dice prendere la data e quindi sottrarre il giorno di settimana da esso. Ma quello che non capisco è perché .astype ('timedelta64 [D]') restituisce tutti gli zeri. –

Problemi correlati