466 Stimmen

Convert DataFrame Spaltentyp von String in Datetime um

Wie kann ich eine DataFrame-Spalte mit Zeichenfolgen (im dd/mm/yyyy-Format) in datetime-Datentyp konvertieren?

713voto

Andy Hayden Punkte 324102

Der einfachste Weg ist die Verwendung von to_datetime:

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

Es bietet auch ein dayfirst Argument für europäische Zeiten (aber Vorsicht, das ist nicht streng).

Hier ist es in Aktion:

In [11]: pd.to_datetime(pd.Series(['05/23/2005']))
Out[11]:
0   2005-05-23 00:00:00
dtype: datetime64[ns]

Sie können ein spezifisches Format übergeben:

In [12]: pd.to_datetime(pd.Series(['05/23/2005']), format="%m/%d/%Y")
Out[12]:
0   2005-05-23
dtype: datetime64[ns]

71voto

sigurdb Punkte 1335

Wenn Ihre Datums-Spalte einen String im Format '2017-01-01' ist, können Sie pandas astype verwenden, um sie in ein Datetime-Format umzuwandeln.

df['date'] = df['date'].astype('datetime64[ns]')

oder verwenden Sie datetime64[D], wenn Sie eine Tagesgenauigkeit und keine Nanosekunden möchten

print(type(df_launath['date'].iloc[0])) 

ergibt

dasselbe wie bei Verwendung von pandas.to_datetime

Sie können es mit anderen Formaten als '%Y-%m-%d' ausprobieren, aber zumindest funktioniert dies.

53voto

Ekhtiar Punkte 823

Sie können das folgende verwenden, wenn Sie knifflige Formate angeben möchten:

df['date_col'] =  pd.to_datetime(df['date_col'], format='%d/%m/%Y')

Weitere Details zum format finden Sie hier:

21voto

otaku Punkte 739

Wenn Sie eine Mischung von Formaten in Ihrem Datum haben, vergessen Sie nicht, infer_datetime_format=True zu setzen, um das Leben einfacher zu machen.

df['date'] = pd.to_datetime(df['date'], infer_datetime_format=True)

Quelle: pd.to_datetime

oder wenn Sie einen individuellen Ansatz wollen:

def autoconvert_datetime(value):
    formats = ['%m/%d/%Y', '%m-%d-%y']  # Formate, die ausprobiert werden sollen
    result_format = '%d-%m-%Y'  # Ausgabeformat
    for dt_format in formats:
        try:
            dt_obj = datetime.strptime(value, dt_format)
            return dt_obj.strftime(result_format)
        except Exception as e:  # wirft eine Ausnahme, wenn das Format nicht übereinstimmt
            pass
    return value  # lass es so, wenn es nicht übereinstimmt

df['date'] = df['date'].apply(autoconvert_datetime)

4voto

not a robot Punkte 3525
Mehrere Datumszeit-Spalten

Wenn Sie mehrere String-Spalten in Datumszeiten umwandeln möchten, dann ist es hilfreich, apply() zu verwenden.

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

Sie können Parameter als kwargs an to_datetime übergeben.

df[['start_date', 'end_date']] = df[['start_date', 'end_date']].apply(pd.to_datetime, format="%m/%d/%Y")

Wenn Sie apply ohne Angabe von axis verwenden, werden die Werte dennoch vektoriell für jede Spalte umgewandelt. apply wird hier benötigt, da pd.to_datetime nur auf eine einzelne Spalte angewendet werden kann. Wenn es auf mehrere Spalten angewendet werden muss, bestehen die Optionen entweder darin, eine explizite for-Schleife zu verwenden oder es an apply zu übergeben. Andererseits sollte vermieden werden, pd.to_datetime mit apply auf eine Spalte aufzurufen (z.B. df['date'].apply(pd.to_datetime)), da dies nicht vektorisiert wäre.


Verwenden Sie format= zur Beschleunigung

Wenn die Spalte eine Zeitkomponente enthält und Sie das Format des Datums/der Zeit kennen, führt das explizite Übergeben des Formats zu einer erheblichen Beschleunigung der Umwandlung. Bei einer Spalte, die nur das Datum enthält, gibt es kaum einen Unterschied. In meinem Projekt betrug der Unterschied für eine Spalte mit 5 Millionen Zeilen riesig: ~2,5 Min vs. 6 Sek.

Es stellt sich heraus, dass das explizite Angeben des Formats etwa 25x schneller ist. Das folgende Laufzeitdiagramm zeigt, dass es je nach Übermittlung des Formats eine enorme Leistungslücke gibt.

timings


Der Code, der zur Erstellung des Diagramms verwendet wurde:

import perfplot
import random

mdYHM = range(1, 13), range(1, 29), range(2000, 2024), range(24), range(60)
perfplot.show(
    kernels=[lambda x: pd.to_datetime(x), lambda x: pd.to_datetime(x, format='%m/%d/%Y %H:%M')],
    labels=['pd.to_datetime(x)', "pd.to_datetime(x, format='%m/%d/%Y %H:%M')"],
    n_range=[2**k for k in range(19)],
    setup=lambda n: pd.Series([f"{m}/{d}/{Y} {H}:{M}" 
                               for m,d,Y,H,M in zip(*[random.choices(e, k=n) for e in mdYHM])]),
    equality_check=pd.Series.equals,
    xlabel='len(df)'
)

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X