2013-10-23 12 views
8

Im Geiste von this answer versuchte ich Folgendes, um eine DataFrame-Spalte mit Datumsangaben in eine Spalte von Sekunden seit der Epoche zu konvertieren.Python Pandas Reihe von Datumsangaben in Sekunden seit der Epoche

df['date'] = (df['date']+datetime.timedelta(hours=2)-datetime.datetime(1970,1,1)) 
df['date'].map(lambda td:td.total_seconds()) 

Der zweite Befehl verursacht den folgenden Fehler, den ich nicht verstehe. Irgendwelche Gedanken darüber, was hier vor sich geht? Ich habe Karte durch Anwendung ersetzt und das hat nichts geholfen.

--------------------------------------------------------------------------- 
AttributeError       Traceback (most recent call last) 
<ipython-input-99-7123e823f995> in <module>() 
----> 1 df['date'].map(lambda td:td.total_seconds()) 

/Users/cpd/.virtualenvs/py27-ipython+pandas/lib/python2.7/site-packages/pandas-0.12.0_937_gb55c790-py2.7-macosx-10.8-x86_64.egg/pandas/core/series.pyc in map(self, arg, na_action) 
    1932    return self._constructor(new_values, index=self.index).__finalize__(self) 
    1933   else: 
-> 1934    mapped = map_f(values, arg) 
    1935    return self._constructor(mapped, index=self.index).__finalize__(self) 
    1936 

/Users/cpd/.virtualenvs/py27-ipython+pandas/lib/python2.7/site-packages/pandas-0.12.0_937_gb55c790-py2.7-macosx-10.8-x86_64.egg/pandas/lib.so in pandas.lib.map_infer (pandas/lib.c:43628)() 

<ipython-input-99-7123e823f995> in <lambda>(td) 
----> 1 df['date'].map(lambda td:td.total_seconds()) 

AttributeError: 'float' object has no attribute 'total_seconds' 
+0

Es scheint, dass die 'date'-Spalte möglicherweise kein datetime64 an erster Stelle ist? – Boud

+1

Enthält die Spalte fehlende Werte? Fehlende Werte führen normalerweise dazu, dass Pandas-Reihen in Schwebezustand versetzt werden, was Verrücktheit verursacht, wenn Sie versuchen, sie als Datumsangaben zu interpretieren. – Abe

+0

@Abe Tatsächlich hatten Sie Recht. Es stellt sich heraus, dass einige Daten in einigen der Datensätze fehlen. Nicht was ich erwartet hatte ... Ack. – Chris

Antwort

12

Update:

In 0.15.0 Timedeltas wurde zu einem vollwertigen dtype.

So wird dies möglich ist (wie auch die Methoden unten)

In [45]: s = Series(pd.timedelta_range('1 day',freq='1S',periods=5))       

In [46]: s.dt.components 
Out[46]: 
    days hours minutes seconds milliseconds microseconds nanoseconds 
0  1  0  0  0    0    0   0 
1  1  0  0  1    0    0   0 
2  1  0  0  2    0    0   0 
3  1  0  0  3    0    0   0 
4  1  0  0  4    0    0   0 

In [47]: s.astype('timedelta64[s]') 
Out[47]: 
0 86400 
1 86401 
2 86402 
3 86403 
4 86404 
dtype: float64 

Ursprüngliche Antwort:

Ich sehe, dass Sie auf dem Master (und 0.13 kommen aus sehr kurz), so unter der Annahme, Sie haben eine Zahl> = 1.7. Mach das. Siehe here für die Dokumentation (dies ist Frequenzumwandlung)

In [5]: df = DataFrame(dict(date = date_range('20130101',periods=10))) 

In [6]: df 
Out[6]: 
       date 
0 2013-01-01 00:00:00 
1 2013-01-02 00:00:00 
2 2013-01-03 00:00:00 
3 2013-01-04 00:00:00 
4 2013-01-05 00:00:00 
5 2013-01-06 00:00:00 
6 2013-01-07 00:00:00 
7 2013-01-08 00:00:00 
8 2013-01-09 00:00:00 
9 2013-01-10 00:00:00 

In [7]: df['date']+timedelta(hours=2)-datetime.datetime(1970,1,1) 
Out[7]: 
0 15706 days, 02:00:00 
1 15707 days, 02:00:00 
2 15708 days, 02:00:00 
3 15709 days, 02:00:00 
4 15710 days, 02:00:00 
5 15711 days, 02:00:00 
6 15712 days, 02:00:00 
7 15713 days, 02:00:00 
8 15714 days, 02:00:00 
9 15715 days, 02:00:00 
Name: date, dtype: timedelta64[ns] 

In [9]: (df['date']+timedelta(hours=2)-datetime.datetime(1970,1,1))/np.timedelta64(1,'s') 
Out[9]: 
0 1357005600 
1 1357092000 
2 1357178400 
3 1357264800 
4 1357351200 
5 1357437600 
6 1357524000 
7 1357610400 
8 1357696800 
9 1357783200 
Name: date, dtype: float64 

Die enthaltenen Werte np.timedelta64[ns] Objekte sind, werden sie nicht die gleichen Methoden wie timedelta Objekte, also ohne total_seconds().

In [10]: s = (df['date']+timedelta(hours=2)-datetime.datetime(1970,1,1)) 

In [11]: s[0] 
Out[11]: numpy.timedelta64(1357005600000000000,'ns') 

Sie können sie AsType in int, und Sie eine ns Einheit zurück.

In [12]: s[0].astype(int) 
Out[12]: 1357005600000000000 

Sie können dies auch tun (aber nur auf einem einzelnen Einheitselement).

In [18]: s[0].astype('timedelta64[s]') 
Out[18]: numpy.timedelta64(1357005600,'s') 
+1

Perfect Jeff, danke! Sobald ich die Zeilen mit fehlenden Daten los war, konnte ich dies direkt auf das neue Problem anwenden. ;-) – Chris

+0

Sie müssen keine fehlenden Werte (NaT) entfernen; sie werden als nan zurückgegeben werden – Jeff

+0

Ich habe momentan keine Zeit, um die Antwort zu bearbeiten (und erneut zu verifizieren), aber in Version 0.13 können jetzt 'astype' Operationen auf eine ganze Serie angewendet werden. Siehe http://pandas.pydata.org/pandas-docs/stable/timeseries.html#time-deltas-conversions oder http://pandas.pydata.org/pandas-docs/stable/whatsnew.html und a Finden Sie auf der Seite nach 'astype'. – TimStaley

Verwandte Themen