datetime dtypes in pandas read_csv

125

Ich lese in einer CSV-Datei mit mehreren Datetime-Spalten. Ich müsste die Datentypen beim Einlesen der Datei festlegen, aber die Datumszeiten scheinen ein Problem zu sein. Zum Beispiel:

headers = ['col1', 'col2', 'col3', 'col4']
dtypes = ['datetime', 'datetime', 'str', 'float']
pd.read_csv(file, sep='\t', header=None, names=headers, dtype=dtypes)

Beim Ausführen wird ein Fehler ausgegeben:

TypeError: Datentyp "datetime" wird nicht verstanden

Das Konvertieren von Spalten nachträglich über pandas.to_datetime () ist keine Option. Ich kann nicht wissen, welche Spalten Datetime-Objekte sind. Diese Informationen können sich ändern und stammen von allem, was meine dtypes-Liste informiert.

Alternativ habe ich versucht, die CSV-Datei mit numpy.genfromtxt zu laden, die dtypes in dieser Funktion festzulegen und dann in einen pandas.dataframe zu konvertieren, aber es verstümmelt die Daten. Jede Hilfe wird sehr geschätzt!

user3221055
quelle

Antworten:

272

Warum funktioniert es nicht

Für read_csv muss kein datetime dtype festgelegt werden, da CSV-Dateien nur Zeichenfolgen, Ganzzahlen und Gleitkommazahlen enthalten können.

Wenn Sie einen dtype auf datetime setzen, interpretieren Pandas die datetime als Objekt, was bedeutet, dass Sie eine Zeichenfolge erhalten.

Pandas Weg, dies zu lösen

Die pandas.read_csv()Funktion hat ein Schlüsselwortargument namensparse_dates

Mit dieser Option können Sie Zeichenfolgen, Gleitkommazahlen oder Ganzzahlen im Handumdrehen mit der Standardeinstellung date_parser( dateutil.parser.parser) in Datumsangaben konvertieren.

headers = ['col1', 'col2', 'col3', 'col4']
dtypes = {'col1': 'str', 'col2': 'str', 'col3': 'str', 'col4': 'float'}
parse_dates = ['col1', 'col2']
pd.read_csv(file, sep='\t', header=None, names=headers, dtype=dtypes, parse_dates=parse_dates)

Dies führt dazu, dass Pandas lesen col1undcol2 als Zeichenfolgen , was höchstwahrscheinlich der Fall ist ("2016-05-05" usw.). Nach dem Lesen der Zeichenfolge wirkt der date_parser für jede Spalte auf diese Zeichenfolge und gibt alles zurück, was diese Funktion zurückgibt .

Definieren Ihrer eigenen Datumsanalysefunktion:

Die pandas.read_csv()Funktion auch hat ein Schlüsselwort Argument aufgerufendate_parser

Wenn Sie dies auf eine Lambda-Funktion setzen, wird diese bestimmte Funktion zum Parsen der Daten verwendet.

GOTCHA WARNUNG

Sie müssen ihm die Funktion geben, nicht die Ausführung der Funktion, daher ist dies korrekt

date_parser = pd.datetools.to_datetime

Das ist falsch :

date_parser = pd.datetools.to_datetime()

Pandas 0.22 Update

pd.datetools.to_datetime wurde nach verlegt date_parser = pd.to_datetime

Danke @stackoverYC

Firelynx
quelle
1
@Drake Ich denke, user3221055 ist nie wirklich auf die Seite zurückgekehrt. Das ist das Problem. Profil sagt "Zuletzt gesehen 20. Mai 14 um 2:35"
Firelynx
2
Dies ist eine langsame Lösung. Siehe dies stattdessen: stackoverflow.com/questions/29882573/…
user1761806
@ user1761806 Hey guter Fund! Ich habe aber einen besseren gemacht. stackoverflow.com/a/46183514/3730397
firelynx
2
Auf Pandas 0.22.0 sagt, pandas.core.datetools.to_datetimeist veraltet, verwenden Sie pd.datetools.to_datetimestattdessen. wie date_parser = pd.to_datetime
folgt
1
Es gibt auch einen convertersParameter, in dem Sie angeben können, welche Spalten welche Konverter haben. parse_dates ist hilfreich und verarbeitet schlechte Daten, ist jedoch langsamer, da jeder Wert getestet und abgeleitet wird. gist.github.com/gjreda/7433f5f70299610d9b6b
Davos
31

Es gibt einen parse_datesParameter read_csv, mit dem Sie die Namen der Spalten definieren können, die als Datum oder Uhrzeit behandelt werden sollen:

date_cols = ['col1', 'col2']
pd.read_csv(file, sep='\t', header=None, names=headers, parse_dates=date_cols)
mrjrdnthms
quelle
Ich hatte einen Fehler, als ich den Namen einer einzelnen Zeichenfolge der Spalte übergab. Jetzt verstehe ich, dass ich die Liste auch für einen einzelnen Wert übergeben musste.
TapanHP
15

Sie können versuchen, tatsächliche Typen anstelle von Zeichenfolgen zu übergeben.

import pandas as pd
from datetime import datetime
headers = ['col1', 'col2', 'col3', 'col4'] 
dtypes = [datetime, datetime, str, float] 
pd.read_csv(file, sep='\t', header=None, names=headers, dtype=dtypes)

Aber es wird wirklich schwierig sein, dies zu diagnostizieren, ohne dass Sie Daten basteln müssen.

Und wirklich, Sie möchten wahrscheinlich, dass Pandas die Daten in TimeStamps analysieren, also könnte das sein:

pd.read_csv(file, sep='\t', header=None, names=headers, parse_dates=True)
Paul H.
quelle
7

Ich habe versucht, die Option dtypes = [datetime, ...] zu verwenden, aber

import pandas as pd
from datetime import datetime
headers = ['col1', 'col2', 'col3', 'col4'] 
dtypes = [datetime, datetime, str, float] 
pd.read_csv(file, sep='\t', header=None, names=headers, dtype=dtypes)

Ich habe folgenden Fehler festgestellt:

TypeError: data type not understood

Die einzige Änderung, die ich vornehmen musste, war, datetime durch datetime.datetime zu ersetzen

import pandas as pd
from datetime import datetime
headers = ['col1', 'col2', 'col3', 'col4'] 
dtypes = [datetime.datetime, datetime.datetime, str, float] 
pd.read_csv(file, sep='\t', header=None, names=headers, dtype=dtypes)
Jose Buraschi
quelle
3
Dies macht den dtype des resultierenden Datenrahmens immer noch zu einem Objekt, nicht zu einer pandas.datetime
firelynx
11
Abgesehen von der Tatsache, dass dies nicht den gewünschten Effekt hat, funktioniert es auch nicht:AttributeError: type object 'datetime.datetime' has no attribute 'datetime'
Gabriel