datetime dtypes in pandas read_csv


127

Sto leggendo in un file CSV con più colonne datetime. Avrei bisogno di impostare i tipi di dati durante la lettura nel file, ma i datetimes sembrano essere un problema. Per esempio:

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

Quando l'esecuzione dà un errore:

TypeError: tipo di dati "datetime" non compreso

La conversione di colonne dopo il fatto, tramite pandas.to_datetime () non è un'opzione non posso sapere quali colonne saranno oggetti datetime. Quelle informazioni possono cambiare e provengono da tutto ciò che informa il mio elenco di tipi.

In alternativa, ho provato a caricare il file csv con numpy.genfromtxt, impostare i dtypes in quella funzione e quindi convertirlo in un pandas.dataframe ma altera i dati. Qualsiasi aiuto è molto apprezzato!

Risposte:


273

Perché non funziona

Non esiste alcun dtype datetime da impostare per read_csv poiché i file csv possono contenere solo stringhe, numeri interi e float.

L'impostazione di un dtype su datetime farà sì che i panda interpretino il datetime come un oggetto, il che significa che ti ritroverai con una stringa.

Pandas modo di risolvere questo problema

La pandas.read_csv()funzione ha un argomento di parola chiave chiamatoparse_dates

Usando questo puoi convertire al volo stringhe, float o interi in datetimes usando il 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)

Ciò farà sì che i panda leggano col1e col2come stringhe, che molto probabilmente sono ("2016-05-05" ecc.) E dopo aver letto la stringa, il date_parser per ogni colonna agirà su quella stringa e restituirà tutto ciò che la funzione restituisce .

Definizione della propria funzione di analisi della data:

La pandas.read_csv()funzione ha anche un argomento di parola chiave chiamatodate_parser

Impostandolo su una funzione lambda, quella particolare funzione verrà utilizzata per l'analisi delle date.

GOTCHA ATTENZIONE

Devi dargli la funzione, non l'esecuzione della funzione, quindi questo è corretto

date_parser = pd.datetools.to_datetime

Questo non è corretto :

date_parser = pd.datetools.to_datetime()

Pandas 0.22 Aggiornare

pd.datetools.to_datetime è stato trasferito a date_parser = pd.to_datetime

Grazie @stackoverYC


1
@ Drake, penso che user3221055 non sia mai tornato sul sito. Questo è il problema. Il profilo dice "Visto l'ultima volta il 20 maggio 14 alle 2:35"
firelynx

2
Questa è una soluzione lenta. Vedere questo, invece: stackoverflow.com/questions/29882573/...
user1761806

@ user1761806 Ehi, buona scoperta! Ma ne ho fatto uno migliore. stackoverflow.com/a/46183514/3730397
firelynx

2
Su panda 0.22.0 dice che pandas.core.datetools.to_datetimeè deprecato, usa pd.datetools.to_datetimeinvece. in questo modo:date_parser = pd.to_datetime
stackoverYC

1
C'è anche un convertersparametro in cui puoi specificare quali colonne hanno quali convertitori. parse_dates è utile e gestisce dati non validi ma è più lento a causa di test e inferenza di
Davos

31

C'è un parse_datesparametro per il read_csvquale ti permette di definire i nomi delle colonne che vuoi trattare come date o datetimes:

date_cols = ['col1', 'col2']
pd.read_csv(file, sep='\t', header=None, names=headers, parse_dates=date_cols)

Ho riscontrato un errore mentre stavo passando il nome di una singola stringa della colonna, ora capisco che dovevo passare anche l'elenco per un singolo valore.
TapanHP

15

Potresti provare a passare tipi effettivi invece di stringhe.

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)

Ma sarà davvero difficile diagnosticare questo senza nessuno dei tuoi dati con cui armeggiare.

E davvero, probabilmente vuoi che i panda analizzino le date in TimeStamps, quindi potrebbe essere:

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

7

Ho provato a usare l'opzione dtypes = [datetime, ...], ma

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)

Ho riscontrato il seguente errore:

TypeError: data type not understood

L'unica modifica che ho dovuto apportare è stata la sostituzione di datetime con 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
Ciò renderà comunque il dtype del dataframe risultante un oggetto, non un pandas.datetime
firelynx

11
A parte il fatto che questo non ha l'effetto desiderato, non funziona nemmeno:AttributeError: type object 'datetime.datetime' has no attribute 'datetime'
Gabriel
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.