dtypes datetime dans pandas read_csv

127

Je lis dans un fichier csv avec plusieurs colonnes datetime. J'aurais besoin de définir les types de données lors de la lecture du fichier, mais les datetimes semblent être un problème. Par exemple:

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

Lorsque l'exécution donne une erreur:

TypeError: type de données "datetime" non compris

La conversion des colonnes après coup, via pandas.to_datetime () n'est pas une option, je ne peux pas savoir quelles colonnes seront des objets datetime. Cette information peut changer et provient de tout ce qui informe ma liste de dtypes.

Alternativement, j'ai essayé de charger le fichier csv avec numpy.genfromtxt, de définir les dtypes dans cette fonction, puis de le convertir en pandas.dataframe mais cela brouille les données. Toute aide est grandement appréciée!

user3221055
la source

Réponses:

273

Pourquoi ça ne marche pas

Il n'y a pas de dtype datetime à définir pour read_csv car les fichiers csv ne peuvent contenir que des chaînes, des entiers et des flottants.

Définir un dtype sur datetime obligera les pandas à interpréter le datetime comme un objet, ce qui signifie que vous vous retrouverez avec une chaîne.

Pandas moyen de résoudre ce problème

le pandas.read_csv() fonction a un argument de mot-clé appeléparse_dates

En utilisant cela, vous pouvez à la volée convertir des chaînes, des flottants ou des entiers en datetimes en utilisant la valeur par défaut 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)

Cela amènera les pandas à lire col1etcol2 sous forme de chaînes, ce qu'ils sont probablement ("2016-05-05", etc.) et après avoir lu la chaîne, le date_parser de chaque colonne agira sur cette chaîne et rendra tout ce que la fonction retourne .

Définition de votre propre fonction d'analyse de date:

La pandas.read_csv()fonction a également un argument de mot-clé appelédate_parser

En définissant ceci sur une fonction lambda, cette fonction particulière sera utilisée pour l'analyse des dates.

AVERTISSEMENT GOTCHA

Vous devez lui donner la fonction, pas l'exécution de la fonction, donc c'est correct

date_parser = pd.datetools.to_datetime

Ceci est incorrect :

date_parser = pd.datetools.to_datetime()

Pandas 0.22 Mise à jour

pd.datetools.to_datetime a été relocalisé à date_parser = pd.to_datetime

Merci @stackoverYC

firelynx
la source
1
@Drake Je pense que user3221055 n'est jamais vraiment revenu sur le site. C'est le problème. Profil dit "Vu pour la dernière fois le 20 mai 14 à 2 h 35"
firelynx
2
C'est une solution lente. Voyez ceci à la place: stackoverflow.com/questions/29882573/…
user1761806
@ user1761806 Hé bonne trouvaille! J'en ai fait un meilleur cependant. stackoverflow.com/a/46183514/3730397
firelynx
2
Sur pandas 0.22.0 dit pandas.core.datetools.to_datetimeest obsolète, utilisez à la pd.datetools.to_datetimeplace. comme ceci:date_parser = pd.to_datetime
stackoverYC
1
Il existe également un convertersparamètre dans lequel vous pouvez spécifier quelles colonnes ont quels convertisseurs. parse_dates est utile et gère les mauvaises données, mais il est plus lent car il teste et infère
Davos
31

Il existe un parse_datesparamètre pour read_csvlequel vous permet de définir les noms des colonnes que vous souhaitez traiter comme dates ou datetimes:

date_cols = ['col1', 'col2']
pd.read_csv(file, sep='\t', header=None, names=headers, parse_dates=date_cols)
mrjrdnthms
la source
J'avais une erreur en passant le nom d'une seule chaîne de colonne, maintenant je comprends que je devais également transmettre la liste pour une seule valeur.
TapanHP
15

Vous pouvez essayer de transmettre des types réels au lieu de chaînes.

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)

Mais il sera vraiment difficile de diagnostiquer cela sans aucune de vos données à bricoler.

Et vraiment, vous voulez probablement que les pandas analysent les dates dans TimeStamps, donc cela pourrait être:

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

J'ai essayé d'utiliser l'option dtypes = [datetime, ...], mais

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)

J'ai rencontré l'erreur suivante:

TypeError: data type not understood

Le seul changement que j'ai dû faire est de remplacer datetime par 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)
José Buraschi
la source
3
Cela fera toujours du dtype du dataframe résultant un objet, pas un pandas.datetime
firelynx
11
Mis à part le fait que cela n'a pas l'effet souhaité, cela ne fonctionne pas non plus:AttributeError: type object 'datetime.datetime' has no attribute 'datetime'
Gabriel