Kombinieren Sie Datums- und Uhrzeitspalten mit Python-Pandas

113

Ich habe einen Pandas-Datenrahmen mit den folgenden Spalten.

Date              Time
01-06-2013      23:00:00
02-06-2013      01:00:00
02-06-2013      21:00:00
02-06-2013      22:00:00
02-06-2013      23:00:00
03-06-2013      01:00:00
03-06-2013      21:00:00
03-06-2013      22:00:00
03-06-2013      23:00:00
04-06-2013      01:00:00

Wie kombiniere ich Daten ['Datum'] und Daten ['Uhrzeit'], um Folgendes zu erhalten? Gibt es eine Möglichkeit, dies zu tun pd.to_datetime?

Date
01-06-2013 23:00:00
02-06-2013 01:00:00
02-06-2013 21:00:00
02-06-2013 22:00:00
02-06-2013 23:00:00
03-06-2013 01:00:00
03-06-2013 21:00:00
03-06-2013 22:00:00
03-06-2013 23:00:00
04-06-2013 01:00:00
Richie
quelle
Danke für alle Antworten. Ich habe die meisten davon ausprobiert, aber immer noch, wenn ich diese Datums- / Uhrzeitinformationen als Teil eines größeren Datenrahmens hinzufüge. In der Spalte Datum / Uhrzeit wird nur das Datum und die Uhrzeitinformationen nicht angezeigt. Sollten wir verstehen, dass die Zeit dort verborgen ist oder entfernt wird?
Karthikeyan

Antworten:

168

Es ist erwähnenswert, dass Sie dies möglicherweise direkt einlesen konnten, z. B. wenn Sie using read_csvverwendet haben parse_dates=[['Date', 'Time']].

Angenommen, dies sind nur Zeichenfolgen, können Sie sie einfach zusammenfügen (mit einem Leerzeichen), sodass Sie Folgendes anwenden können to_datetime:

In [11]: df['Date'] + ' ' + df['Time']
Out[11]:
0    01-06-2013 23:00:00
1    02-06-2013 01:00:00
2    02-06-2013 21:00:00
3    02-06-2013 22:00:00
4    02-06-2013 23:00:00
5    03-06-2013 01:00:00
6    03-06-2013 21:00:00
7    03-06-2013 22:00:00
8    03-06-2013 23:00:00
9    04-06-2013 01:00:00
dtype: object

In [12]: pd.to_datetime(df['Date'] + ' ' + df['Time'])
Out[12]:
0   2013-01-06 23:00:00
1   2013-02-06 01:00:00
2   2013-02-06 21:00:00
3   2013-02-06 22:00:00
4   2013-02-06 23:00:00
5   2013-03-06 01:00:00
6   2013-03-06 21:00:00
7   2013-03-06 22:00:00
8   2013-03-06 23:00:00
9   2013-04-06 01:00:00
dtype: datetime64[ns]

Hinweis: Überraschenderweise (für mich) funktioniert dies gut, wenn NaNs in NaT konvertiert werden, aber es ist erwähnenswert, dass die Konvertierung (möglicherweise unter Verwendung des raiseArguments).

Andy Hayden
quelle
6
Ich wusste nichts über die automatische Kombinationsfunktion und sie funktioniert auch mit mehreren Einträgen, wie zum Beispiel : parse_dates=[['Start date', 'Start time'], ['End date', 'End time']]). Pandas <3
5agado
43

Die akzeptierte Antwort funktioniert für Spalten vom Datentyp string. Der Vollständigkeit halber: Ich stoße auf diese Frage, wenn ich suche, wie dies zu tun ist, wenn die Spalten Datentypen haben: Datum und Uhrzeit.

df.apply(lambda r : pd.datetime.combine(r['date_column_name'],r['time_column_name']),1)
jka.ne
quelle
2
Ich kann nichts über den timeTyp in Pandas finden. Ich habe eher ein timedelta(und ein datetime), in welchem ​​Fall Sie sie nur hinzufügen müssen, siehe meine Antwort
toto_tico
Wenn ich eine Excel-Spalte, die Excel als "Zeit" identifiziert, 'pd.read_excel' ', liest Pandas sie auch automatisch als "Zeit", ohne dass ein Parsing-Argument erforderlich ist. Danke für diese Lösung. +1
Saeed
1
Nur eine Anmerkung, ab Pandas 1.0.0 pd.datetime ist veraltet und es wird empfohlen, datetimestattdessen nur das Modul explizit zu importieren .
CopOnTheRun
15

Sie können dies verwenden, um Datum und Uhrzeit in derselben Spalte des Datenrahmens zusammenzuführen.

import pandas as pd    
data_file = 'data.csv' #path of your file

CSV-Datei mit zusammengeführten Spalten lesen Date_Time:

data = pd.read_csv(data_file, parse_dates=[['Date', 'Time']]) 

Sie können diese Zeile verwenden, um auch beide anderen Spalten beizubehalten.

data.set_index(['Date', 'Time'], drop=False)
MK Rana
quelle
Sie können auch benutzerdefinierte verwenden date_parser, zum Beispielparser = lambda date: pd.datetime.strptime(date, '%d-%b-%y %H:%M:%S')
Serendipity
11

Sie können die Spalten umwandeln, wenn die Typen unterschiedlich sind (Datum / Uhrzeit und Zeitstempel oder str) und to_datetime verwenden:

df.loc[:,'Date'] = pd.to_datetime(df.Date.astype(str)+' '+df.Time.astype(str))

Ergebnis:

0   2013-01-06 23:00:00
1   2013-02-06 01:00:00
2   2013-02-06 21:00:00
3   2013-02-06 22:00:00
4   2013-02-06 23:00:00
5   2013-03-06 01:00:00
6   2013-03-06 21:00:00
7   2013-03-06 22:00:00
8   2013-03-06 23:00:00
9   2013-04-06 01:00:00

Beste,

Chris PERE
quelle
10

Ich habe nicht genug Ruf, um jka.ne zu kommentieren, also:

Ich musste die Zeile von jka.ne ändern, damit es funktioniert:

df.apply(lambda r : pd.datetime.combine(r['date_column_name'],r['time_column_name']).time(),1)

Dies könnte anderen helfen.

Außerdem habe ich einen anderen Ansatz getestet, replaceanstatt combine:

def combine_date_time(df, datecol, timecol):
    return df.apply(lambda row: row[datecol].replace(
                                hour=row[timecol].hour,
                                minute=row[timecol].minute),
                    axis=1)

was im Fall des OP wäre:

combine_date_time(df, 'Date', 'Time')

Ich habe beide Ansätze für einen relativ großen Datensatz (> 500.000 Zeilen) zeitlich festgelegt, und beide haben ähnliche Laufzeiten, aber die Verwendung combineist schneller (59s für replacevs 50s für combine).

jabellcu
quelle
5

Die Antwort hängt wirklich davon ab, welche Spaltentypen Sie verwenden . In meinem Fall hatte ich datetimeund timedelta.

> df[['Date','Time']].dtypes
Date     datetime64[ns]
Time    timedelta64[ns]

Wenn dies der Fall ist, müssen Sie nur die Spalten hinzufügen:

> df['Date'] + df['Time']
toto_tico
quelle
Die akzeptierte Antwort geht davon aus Strings: „Unter der Annahme , dies ist nur Strings Sie sie einfach zusammen (mit Leerzeichen) hinzufügen könnten“ . Meine Antworten sind für datetimeund timedelta. Die Hauptantwort stellt irgendwie fest, dass die Spalten Zeichenfolgen waren, oder vielleicht war es nur die Antwort, die für diejenige funktionierte, die die Frage gestellt hat.
toto_tico
4

Sie können auch datetimeohne Verkettung von Zeichenfolgen konvertieren , indem Sie datetimeund timedeltaObjekte kombinieren . In Kombination mit pd.DataFrame.popkönnen Sie die Quellenserien gleichzeitig entfernen:

df['DateTime'] = pd.to_datetime(df.pop('Date')) + pd.to_timedelta(df.pop('Time'))

print(df)

             DateTime
0 2013-01-06 23:00:00
1 2013-02-06 01:00:00
2 2013-02-06 21:00:00
3 2013-02-06 22:00:00
4 2013-02-06 23:00:00
5 2013-03-06 01:00:00
6 2013-03-06 21:00:00
7 2013-03-06 22:00:00
8 2013-03-06 23:00:00
9 2013-04-06 01:00:00

print(df.dtypes)

DateTime    datetime64[ns]
dtype: object
jpp
quelle
1
Tolle allgemeine Lösung! Ich hatte Datum datetime Datum und Typ str Zeit und das funktionierte.
Spatz
3

Stellen Sie zunächst sicher, dass Sie die richtigen Datentypen haben:

df["Date"] = pd.to_datetime(df["Date"])
df["Time"] = pd.to_timedelta(df["Time"])

Dann kombinieren Sie sie einfach:

df["DateTime"] = df["Date"] + df["Time"]
Warteschlange
quelle
2

Verwenden Sie die combineFunktion:

datetime.datetime.combine(date, time)
Stephen
quelle
2

Mein Datensatz hatte einige Tage lang Auflösungsdaten von 1 Sekunde und das Parsen mit den hier vorgeschlagenen Methoden war sehr langsam. Stattdessen habe ich verwendet:

dates = pandas.to_datetime(df.Date, cache=True)
times = pandas.to_timedelta(df.Time)
datetimes  = dates + times

Beachten Sie, dass die Verwendung von cache=Truedas Parsen der Daten sehr effizient macht, da meine Dateien nur einige eindeutige Daten enthalten, was für eine kombinierte Datums- und Zeitspalte nicht gilt.

tgbrooks
quelle
Das würde ich tun.
Yaakov Bressler
1

DATEN:

<TICKER>, <PER>, <DATE>, <TIME> , <OPEN>, <HIGH>, <LOW>, <CLOSE>, <VOL> SPFB.RTS, 1, 20190103,100100 , 106580.0000000,107260.0000000,106570.0000000 107230.0000000,3726

CODE:

data.columns = ['ticker', 'per', 'date', 'time', 'open', 'high', 'low', 'close', 'vol']    
data.datetime = pd.to_datetime(data.date.astype(str) + ' ' + data.time.astype(str), format='%Y%m%d %H%M%S')
hacknull
quelle