Wie konvertiere ich Daten in einem Pandas-Datenrahmen in einen Datumsdatentyp?


102

Ich habe einen Pandas-Datenrahmen, eine der Spalten enthält Datumszeichenfolgen im Format YYYY-MM-DD

Zum Beispiel '2013-10-28'

Im Moment ist das dtypeder Spalte object.

Wie konvertiere ich die Spaltenwerte in das Pandas-Datumsformat?

Antworten:


108

Verwenden Sie Astype

In [31]: df
Out[31]: 
   a        time
0  1  2013-01-01
1  2  2013-01-02
2  3  2013-01-03

In [32]: df['time'] = df['time'].astype('datetime64[ns]')

In [33]: df
Out[33]: 
   a                time
0  1 2013-01-01 00:00:00
1  2 2013-01-02 00:00:00
2  3 2013-01-03 00:00:00

1
Schön - danke - wie werde ich die 00:00:00 am Ende eines jeden Termins los?
user7289

1
Der Pandas-Zeitstempel hat sowohl Datum als auch Uhrzeit. Meinst du es in Python-Datumsobjekt konvertieren?
Warten

6
Sie können es durch konvertierendf['time'] = [time.date() for time in df['time']]
waitingkuo

3
Was bedeutet [ns]? Können Sie die Textzeichenfolge zu einem Datum machen und den Zeitteil dieses Datums entfernen?
Yoshiserry

1
@yoshiserry Es sind Nanosekunden und die Art und Weise, wie die Daten unter der Haube gespeichert werden, sobald sie ordnungsgemäß konvertiert wurden (Epochenzeit in Nanosekunden).
Andy Hayden

111

Im Wesentlichen äquivalent zu @waitingkuo, aber ich würde es to_datetimehier verwenden (es scheint ein wenig sauberer zu sein und bietet einige zusätzliche Funktionen, z. B. dayfirst):

In [11]: df
Out[11]:
   a        time
0  1  2013-01-01
1  2  2013-01-02
2  3  2013-01-03

In [12]: pd.to_datetime(df['time'])
Out[12]:
0   2013-01-01 00:00:00
1   2013-01-02 00:00:00
2   2013-01-03 00:00:00
Name: time, dtype: datetime64[ns]

In [13]: df['time'] = pd.to_datetime(df['time'])

In [14]: df
Out[14]:
   a                time
0  1 2013-01-01 00:00:00
1  2 2013-01-02 00:00:00
2  3 2013-01-03 00:00:00

Handhabung ValueErrors
Wenn Sie in eine Situation geraten, in der Sie dies tun

df['time'] = pd.to_datetime(df['time'])

Wirft a

ValueError: Unknown string format

Das heißt, Sie haben ungültige (nicht erzwungene) Werte. Wenn Sie damit einverstanden sind, dass sie konvertiert werden pd.NaT, können Sie ein errors='coerce'Argument hinzufügen zu to_datetime:

df['time'] = pd.to_datetime(df['time'], errors='coerce')

Hallo Leute, @AndyHayden, kannst du den Zeitteil vom Datum entfernen? Ich brauche diesen Teil nicht?
Yoshiserry

In Pandas '0.13.1 werden die nachfolgenden 00: 00: 00s nicht angezeigt.
Andy Hayden

und was ist mit in anderen Versionen, wie entfernen / und / oder zeigen wir sie nicht an?
Yoshiserry

Ich denke nicht, dass dies auf eine nette Art und Weise gemacht werden kann. Es wird diskutiert, date_format wie float_format (das Sie gesehen haben) hinzuzufügen. Ich empfehle trotzdem ein Upgrade.
Andy Hayden

Mein Problem ist, dass mein Datum in diesem Format vorliegt ... 41516.43, und ich erhalte diesen Fehler. Ich würde erwarten, dass es so etwas wie 2014-02-03 in der neuen Spalte zurückgibt?! DER FEHLER: # Datumswerte in der Spalte "load_date" in Datumsangaben konvertieren budget_dataset ['date_last_load'] = pd.to_datetime (budget_dataset ['load_date']) budget_dataset -c: 2: SettingWithCopyWarning: Ein Wert versucht, auf a gesetzt zu werden Kopie eines Slice aus einem DataFrame. Versuchen Sie stattdessen, .loc [row_index, col_indexer] = value zu verwenden
yoshiserry

35

Ich stelle mir vor, dass viele Daten aus CSV-Dateien in Pandas eingehen. In diesem Fall können Sie das Datum während des ersten CSV-Lesevorgangs einfach konvertieren:

dfcsv = pd.read_csv('xyz.csv', parse_dates=[0])Dabei bezieht sich die 0 auf die Spalte, in der sich das Datum befindet.
Sie können dort auch hinzufügen, , index_col=0wenn das Datum Ihr Index sein soll.

Siehe https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.read_csv.html


Danke, genau das brauchte ich. Die Dokumentation wurde verschoben. Sie finden sie hier: pandas.pydata.org/pandas-docs/stable/reference/api/…
Sastibe

24

Jetzt können Sie tun df['column'].dt.date

Beachten Sie, dass es sich bei Datetime-Objekten nicht um Pandas handelt, wenn Sie nicht die Stunde sehen, zu der alle 00:00:00 sind. Das ist ein iPython-Notebook, das versucht, die Dinge hübsch aussehen zu lassen.


2
Dieser funktioniert nicht für mich, er beschwert sich: Kann nur .dt Accessor mit datetimelike Werte verwenden
Smishra

1
Möglicherweise müssen Sie df[col] = pd.to_datetime(df[col])zuerst Ihre Spalte in Datums- / Uhrzeitobjekte konvertieren.
szeitlin

Das Problem bei dieser Antwort ist, dass sie die Spalte konvertiert, in dtype = objectdie erheblich mehr Speicher belegt wird als eine echte datetime dtypein Pandas.
elPastor

6

Eine andere Möglichkeit, dies zu tun, funktioniert gut, wenn Sie mehrere Spalten in datetime konvertieren müssen.

cols = ['date1','date2']
df[cols] = df[cols].apply(pd.to_datetime)

Frage fragen nach Datum nicht Datum / Uhrzeit.
Mark Andersen

@MarkAndersen Solange Sie datenur Werte in Ihren Spalten haben, werden bei der Konvertierung in datetime nur die entsprechenden Informationen beibehalten. Wenn Sie explizit konvertieren df['datetime_col'].dt.date, wird dies zu einem objectdtype führen. Verlust in der Speicherverwaltung.
Sumanth Lazarus

4

Wenn Sie das DATE- und nicht das DATETIME-Format erhalten möchten:

df["id_date"] = pd.to_datetime(df["id_date"]).dt.date

1

Es kann vorkommen, dass Daten auf eine andere Häufigkeit umgerechnet werden müssen. In diesem Fall würde ich vorschlagen, einen Index nach Datum festzulegen.

#set an index by dates
df.set_index(['time'], drop=True, inplace=True)

Danach können Sie einfacher in das Datumsformat konvertieren, das Sie am meisten benötigen. Im Folgenden konvertiere ich nacheinander in eine Reihe von Datumsformaten, wobei ich am Anfang des Monats eine Reihe von Tagesdaten erhalte.

#Convert to daily dates
df.index = pd.DatetimeIndex(data=df.index)

#Convert to monthly dates
df.index = df.index.to_period(freq='M')

#Convert to strings
df.index = df.index.strftime('%Y-%m')

#Convert to daily dates
df.index = pd.DatetimeIndex(data=df.index)

Der Kürze halber zeige ich nicht, dass ich nach jeder Zeile oben den folgenden Code ausführe:

print(df.index)
print(df.index.dtype)
print(type(df.index))

Dies gibt mir die folgende Ausgabe:

Index(['2013-01-01', '2013-01-02', '2013-01-03'], dtype='object', name='time')
object
<class 'pandas.core.indexes.base.Index'>

DatetimeIndex(['2013-01-01', '2013-01-02', '2013-01-03'], dtype='datetime64[ns]', name='time', freq=None)
datetime64[ns]
<class 'pandas.core.indexes.datetimes.DatetimeIndex'>

PeriodIndex(['2013-01', '2013-01', '2013-01'], dtype='period[M]', name='time', freq='M')
period[M]
<class 'pandas.core.indexes.period.PeriodIndex'>

Index(['2013-01', '2013-01', '2013-01'], dtype='object')
object
<class 'pandas.core.indexes.base.Index'>

DatetimeIndex(['2013-01-01', '2013-01-01', '2013-01-01'], dtype='datetime64[ns]', freq=None)
datetime64[ns]
<class 'pandas.core.indexes.datetimes.DatetimeIndex'>

0

Versuchen Sie, eine der Zeilen mit der Funktion pd.to_datetime in einen Zeitstempel zu konvertieren, und ordnen Sie das Formular dann mit .map der gesamten Spalte zu


0
 #   Column          Non-Null Count   Dtype         
---  ------          --------------   -----         
 0   startDay        110526 non-null  object
 1   endDay          110526 non-null  object

import pandas as pd

df['startDay'] = pd.to_datetime(df.startDay)

df['endDay'] = pd.to_datetime(df.endDay)

 #   Column          Non-Null Count   Dtype         
---  ------          --------------   -----         
 0   startDay        110526 non-null  datetime64[ns]
 1   endDay          110526 non-null  datetime64[ns]
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.