datetime dtypes w pandach read_csv

127

Czytam w pliku csv z wieloma kolumnami z datą i godziną. Musiałbym ustawić typy danych po wczytaniu pliku, ale czasy dat wydają się być problemem. Na przykład:

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

Gdy run wyświetla błąd:

Błąd typu: niezrozumiany typ danych „datetime”

Konwersja kolumn po fakcie za pomocą pandas.to_datetime () nie jest opcją. Nie wiem, które kolumny będą obiektami datetime. Te informacje mogą się zmieniać i pochodzą z wszystkiego, co informuje o mojej liście typów.

Alternatywnie, próbowałem załadować plik csv za pomocą numpy.genfromtxt, ustawić dtypes w tej funkcji, a następnie przekonwertować na pandas.dataframe, ale zniekształca dane. Każda pomoc jest mile widziana!

user3221055
źródło

Odpowiedzi:

273

Dlaczego to nie działa

Dla read_csv nie można ustawić wartości daty i godziny, ponieważ pliki csv mogą zawierać tylko łańcuchy, liczby całkowite i zmiennoprzecinkowe.

Ustawienie typu dtype na datetime sprawi, że pandy zinterpretują datę i godzinę jako obiekt, co oznacza, że ​​otrzymasz ciąg.

Pandy sposób na rozwiązanie tego problemu

pandas.read_csv()Funkcja ma argumentu słowa kluczowego nazwieparse_dates

Używając tego, możesz w locie konwertować ciągi, liczby zmiennoprzecinkowe lub liczby całkowite na czasy danych przy użyciu metody default date_parser( dateutil.parser.parser)

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)

Spowoduje to, że pandy będą odczytywać col1i col2jako ciągi znaków, którymi najprawdopodobniej są („2016-05-05” itp.), A po przeczytaniu ciągu, parametr date_parser dla każdej kolumny zadziała na ten ciąg i zwróci cokolwiek zwraca funkcja .

Definiowanie własnej funkcji parsowania daty:

pandas.read_csv()Funkcja również ma argumentu słowa kluczowego nazwiedate_parser

Ustawienie tego na funkcję lambda spowoduje, że ta konkretna funkcja będzie używana do analizowania dat.

OSTRZEŻENIE GOTCHA

Musisz nadać mu funkcję, a nie wykonanie funkcji, więc jest to poprawne

date_parser = pd.datetools.to_datetime

To jest nieprawidłowe :

date_parser = pd.datetools.to_datetime()

Pandy 0.22 Update

pd.datetools.to_datetime został przeniesiony do date_parser = pd.to_datetime

Dzięki @stackoverYC

firelynx
źródło
1
@Drake Myślę, że user3221055 nigdy tak naprawdę nie wrócił na stronę. To jest problem. Profil mówi: „Ostatnio widziano 20 maja 2014 o 2:35”
firelynx
2
To powolne rozwiązanie. Zamiast tego zobacz: stackoverflow.com/questions/29882573/ ...
user1761806
@ user1761806 Hej, dobre znalezisko! Zrobiłem jednak lepszy. stackoverflow.com/a/46183514/3730397
firelynx
2
Na pandach 0.22.0 mówi, że pandas.core.datetools.to_datetimejest przestarzałe, użyj pd.datetools.to_datetimezamiast tego. w ten sposób:date_parser = pd.to_datetime
stackoverYC
1
Istnieje również convertersparametr, w którym możesz określić, które kolumny mają które konwertery. parse_dates jest pomocny i obsługuje złe dane, ale jest wolniejszy, ponieważ testuje i wnioskuje o każdej wartości gist.github.com/gjreda/7433f5f70299610d9b6b
Davos
31

Istnieje parse_datesparametr, dla read_csvktórego można zdefiniować nazwy kolumn, które mają być traktowane jako daty lub godziny:

date_cols = ['col1', 'col2']
pd.read_csv(file, sep='\t', header=None, names=headers, parse_dates=date_cols)
mrjrdnthms
źródło
Miałem błąd, gdy podawałem pojedynczy ciąg nazwy kolumny, teraz rozumiem, że muszę również przekazać listę dla pojedynczej wartości.
TapanHP,
15

Możesz spróbować przekazać rzeczywiste typy zamiast ciągów.

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)

Ale będzie to naprawdę trudne do zdiagnozowania bez żadnych danych do majstrowania.

I naprawdę, prawdopodobnie chcesz, aby pandy analizowały daty na znaczniki czasu, więc może to być:

pd.read_csv(file, sep='\t', header=None, names=headers, parse_dates=True)
Paul H.
źródło
7

Próbowałem użyć opcji dtypes = [datetime, ...], ale

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)

Napotkałem następujący błąd:

TypeError: data type not understood

Jedyną zmianą, jaką musiałem dokonać, było zastąpienie datetime przez datetime.datetime

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
źródło
3
Spowoduje to, że typ dtype wynikowej ramki danych będzie obiektem, a nie pandą. Czas
firelynx
11
Pomijając fakt, że nie daje to pożądanego efektu, to też nie działa:AttributeError: type object 'datetime.datetime' has no attribute 'datetime'
Gabriel