222 votes

Est-ce que pandas peut lire automatiquement les dates d'un fichier CSV ?

Aujourd'hui, j'ai été positivement surpris par le fait qu'en lisant les données d'un fichier de données (par exemple), pandas est capable de reconnaître les types de valeurs :

df = pandas.read_csv('test.dat', delimiter=r"\s+", names=['col1','col2','col3'])

Par exemple, il peut être vérifié de cette façon :

for i, r in df.iterrows():
    print type(r['col1']), type(r['col2']), type(r['col3'])

En particulier, les entiers, les flottants et les chaînes de caractères ont été reconnus correctement. Cependant, j'ai une colonne qui contient des dates au format suivant : 2013-6-4 . Ces dates ont été reconnues comme des chaînes de caractères (et non comme des objets de date python). Existe-t-il un moyen d'"apprendre" à pandas à reconnaître les dates ?

445voto

Rutger Kassies Points 7713

Vous devez ajouter parse_dates=True ou parse_dates=['column name'] lors de la lecture, c'est généralement suffisant pour l'analyser comme par magie. Mais il y a toujours des formats bizarres qui doivent être définis manuellement. Dans ce cas, vous pouvez également ajouter une fonction d'analyseur de date, ce qui est la manière la plus flexible possible.

Supposons que vous ayez une colonne 'datetime' avec votre chaîne de caractères :

from datetime import datetime
dateparse = lambda x: datetime.strptime(x, '%Y-%m-%d %H:%M:%S')

df = pd.read_csv(infile, parse_dates=['datetime'], date_parser=dateparse)

De cette façon, vous pouvez même combiner plusieurs colonnes en une seule colonne de date, ce qui fusionne une colonne de date et une colonne d'heure en une seule colonne de date :

dateparse = lambda x: datetime.strptime(x, '%Y-%m-%d %H:%M:%S')

df = pd.read_csv(infile, parse_dates={'datetime': ['date', 'time']}, date_parser=dateparse)

Vous pouvez trouver des directives (c'est-à-dire les lettres à utiliser pour les différents formats) pour strptime y strftime dans cette page .

30voto

Sean Points 660

Peut-être que l'interface de pandas a changé depuis la réponse de @Rutger, mais dans la version que j'utilise (0.15.2), la fonction date_parser reçoit une liste de dates au lieu d'une seule valeur. Dans ce cas, son code devrait être mis à jour comme suit :

from datetime import datetime
import pandas as pd

dateparse = lambda dates: [datetime.strptime(d, '%Y-%m-%d %H:%M:%S') for d in dates]

df = pd.read_csv('test.dat', parse_dates=['datetime'], date_parser=dateparse)

Puisque l'auteur de la question initiale a dit qu'il voulait des dates et que les dates sont dans la base de données de l'ONU. 2013-6-4 le format dateparse devrait vraiment être :

dateparse = lambda dates: [datetime.strptime(d, '%Y-%m-%d').date() for d in dates]

19voto

eugene y Points 37378

Vous pourriez utiliser pandas.to_datetime() comme recommandé dans la documentation de pandas.read_csv() :

Si une colonne ou un index contient une date non séparable, la colonne entière ou l'index sera retourné tel quel sous la forme d'un type de données objet. Pour l'analyse non standard d'une date, utilisez pd.to_datetime après pd.read_csv .

Démonstration :

>>> D = {'date': '2013-6-4'}
>>> df = pd.DataFrame(D, index=[0])
>>> df
       date
0  2013-6-4
>>> df.dtypes
date    object
dtype: object
>>> df['date'] = pd.to_datetime(df.date, format='%Y-%m-%d')
>>> df
        date
0 2013-06-04
>>> df.dtypes
date    datetime64[ns]
dtype: object

13voto

IamTheWalrus Points 246

Lors de la fusion de deux colonnes en une seule colonne de date, la réponse acceptée génère une erreur (pandas version 0.20.3), car les colonnes sont envoyées séparément à la fonction date_parser.

Les travaux suivants :

def dateparse(d,t):
    dt = d + " " + t
    return pd.datetime.strptime(dt, '%d/%m/%Y %H:%M:%S')

df = pd.read_csv(infile, parse_dates={'datetime': ['date', 'time']}, date_parser=dateparse)

10voto

Joop Points 1108

La méthode pandas read_csv est idéale pour analyser les dates. Documentation complète à l'adresse http://pandas.pydata.org/pandas-docs/stable/generated/pandas.io.parsers.read_csv.html

vous pouvez même avoir les différentes parties de la date dans des colonnes différentes et passer le paramètre :

parse_dates : boolean, list of ints or names, list of lists, or dict
If True -> try parsing the index. If [1, 2, 3] -> try parsing columns 1, 2, 3 each as a
separate date column. If [[1, 3]] -> combine columns 1 and 3 and parse as a single date
column. {‘foo’ : [1, 3]} -> parse columns 1, 3 as date and call result ‘foo’

La détection par défaut des dates fonctionne bien, mais elle semble privilégier les formats de date nord-américains. Si vous vivez ailleurs, vous pouvez parfois être surpris par les résultats. Autant que je m'en souvienne, 1/6/2000 signifie le 6 janvier aux Etats-Unis, alors que le 1er juin est le format que j'utilise chez moi. Il est assez intelligent pour les faire basculer si des dates comme 23/6/2000 sont utilisées. Il est probablement plus sûr de rester avec des variations de date de type AAAAMMJD. Je m'excuse auprès des développeurs de pandas, mais je ne l'ai pas testé avec des dates locales récemment.

vous pouvez utiliser le paramètre date_parser pour passer une fonction permettant de convertir votre format.

date_parser : function
Function to use for converting a sequence of string columns to an array of datetime
instances. The default uses dateutil.parser.parser to do the conversion.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X