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!

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


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)

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)

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)

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
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.