estraendo giorni da un valore numpy.timedelta64


87

Sto usando panda / python e ho due serie temporali di data s1 e s2, che sono state generate utilizzando la funzione 'to_datetime' su un campo del df contenente date / ore.

Quando sottraggo s1 da s2

s3 = s2 - s1

Ottengo una serie, s3, di tipo

timedelta64 [ns]

0    385 days, 04:10:36
1     57 days, 22:54:00
2    642 days, 21:15:23
3    615 days, 00:55:44
4    160 days, 22:13:35
5    196 days, 23:06:49
6     23 days, 22:57:17
7      2 days, 22:17:31
8    622 days, 01:29:25
9     79 days, 20:15:14
10    23 days, 22:46:51
11   268 days, 19:23:04
12                  NaT
13                  NaT
14   583 days, 03:40:39

Come guardo 1 elemento della serie:

s3 [10]

Ottengo qualcosa del genere:

numpy.timedelta64 (2069211000000000, 'ns')

Come estraggo i giorni da s3 e magari li mantengo come numeri interi (non così interessato a ore / minuti ecc.)?

Grazie in anticipo per qualsiasi aiuto.


4
solo per tua informazione, in procinto di fondersi in panda padroneggia questa funzionalità: github.com/pydata/pandas/pull/4534 (puoi farlo su 0.12 e prima di:s.apply(lambda x: x / np.timedelta64(1,'D'))
Jeff

Risposte:


146

Puoi convertirlo in un timedelta con una precisione giornaliera. Per estrarre il valore intero di giorni, dividerlo con un timedelta di un giorno.

>>> x = np.timedelta64(2069211000000000, 'ns')
>>> days = x.astype('timedelta64[D]')
>>> days / np.timedelta64(1, 'D')
23

Oppure, come suggerito @PhillipCloud, proprio days.astype(int)dal momento che la timedeltaè solo un intero a 64 bit che viene interpretato in vari modi a seconda del secondo parametro è stato passato a ( 'D', 'ns', ...).

Puoi trovare ulteriori informazioni al riguardo qui .


16
Puoi anche fare days.item().dayso days.astype(int).
Phillip Cloud

1
le versioni più recenti dei panda supportano un tipo Timedelta completo, vedere i documenti qui: pandas.pydata.org/pandas-docs/stable/timedeltas.html
Jeff

Questo è un buon candidato per .apply. Puoi farlo nella stessa riga in cui calcoli i valori delle colonne inserendo .apply (lambda x: x / np.timedelta64 (1, 'D')) alla fine per applicare la conversione a livello di colonna. es. s3 = (s1-s2) .apply (lambda x: x / np.timedelta64 (1, 'D')).
Ezekiel Kruglick

2
Questo metodo astype('timedelta64[D]') (circa 96 ms) è molto più efficiente di dt.days.(circa 24 secondi) per 4.000.000 di righe.
Pengju Zhao

37

Utilizzare dt.daysper ottenere l'attributo dei giorni come numero intero.

Ad esempio:

In [14]: s = pd.Series(pd.timedelta_range(start='1 days', end='12 days', freq='3000T'))

In [15]: s
Out[15]: 
0    1 days 00:00:00
1    3 days 02:00:00
2    5 days 04:00:00
3    7 days 06:00:00
4    9 days 08:00:00
5   11 days 10:00:00
dtype: timedelta64[ns]

In [16]: s.dt.days
Out[16]: 
0     1
1     3
2     5
3     7
4     9
5    11
dtype: int64

Più in generale - Puoi utilizzare la .componentsproprietà per accedere a una forma ridotta di timedelta.

In [17]: s.dt.components
Out[17]: 
   days  hours  minutes  seconds  milliseconds  microseconds  nanoseconds
0     1      0        0        0             0             0            0
1     3      2        0        0             0             0            0
2     5      4        0        0             0             0            0
3     7      6        0        0             0             0            0
4     9      8        0        0             0             0            0
5    11     10        0        0             0             0            0

Ora, per ottenere il file hours attributo:

In [23]: s.dt.components.hours
Out[23]: 
0     0
1     2
2     4
3     6
4     8
5    10
Name: hours, dtype: int64

+1 - Questo è il modo migliore per farlo attualmente poiché il pacchetto panda è progredito da quando è stata posta questa domanda.
Austin A

7

Supponiamo di avere una serie timedelta:

import pandas as pd
from datetime import datetime
z = pd.DataFrame({'a':[datetime.strptime('20150101', '%Y%m%d')],'b':[datetime.strptime('20140601', '%Y%m%d')]})

td_series = (z['a'] - z['b'])

Un modo per convertire questa colonna o serie timedelta è eseguirne il cast su un oggetto Timedelta (panda 0.15.0+) e quindi estrarre i giorni dall'oggetto:

td_series.astype(pd.Timedelta).apply(lambda l: l.days)

Un altro modo è lanciare la serie come timedelta64 in giorni e poi lanciarla come int:

td_series.astype('timedelta64[D]').astype(int)
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.