web-dev-qa-db-fra.com

Spécification du format de date lors de la conversion avec pandas.to_datetime

J'ai des données dans un fichier csv avec des dates stockées sous forme de chaînes dans un format standard britannique - %d/%m/%Y - ce qui signifie qu'ils ressemblent à:

12/01/2012
30/01/2012

Les exemples ci-dessus représentent les 12 janvier 2012 et 30 janvier 2012.

Lorsque j'importe ces données avec pandas version 0.11.0, j'ai appliqué la transformation suivante:

import pandas as pd
...
cpts.Date = cpts.Date.apply(pd.to_datetime)

mais il a converti les dates de manière incohérente. Pour utiliser mon exemple existant, le 12/01/2012 se convertirait en objet datetime représentant le 1er décembre 2012 mais le 30/01/2012 se convertirait en 30 janvier 2012, ce que je veux.

Après avoir regardé cette question j'ai essayé:

cpts.Date = cpts.Date.apply(pd.to_datetime, format='%d/%m/%Y')

mais les résultats sont exactement les mêmes. Le code source suggère que je fais les choses correctement donc je suis à perte. Est-ce que quelqu'un sait ce que je fais mal?

21
cms_mgr

Vous pouvez utiliser le parse_dates option de read_csv pour effectuer la conversion directement lors de la lecture de vos données.
L'astuce consiste à utiliser dayfirst=True pour indiquer que vos dates commencent par le jour et non par le mois. Voir ici pour plus d'informations: http://pandas.pydata.org/pandas-docs/dev/generated/pandas.io.parsers.read_csv.html

Quand vos dates doivent être l'index:

>>> import pandas as pd
>>> from StringIO import StringIO
>>> s = StringIO("""date,value
... 12/01/2012,1
... 12/01/2012,2
... 30/01/2012,3""")
>>> 
>>> pd.read_csv(s, index_col=0, parse_dates=True, dayfirst=True)
            value
date             
2012-01-12      1
2012-01-12      2
2012-01-30      3

Ou lorsque vos dates sont juste dans une certaine colonne:

>>> s = StringIO("""date
... 12/01/2012
... 12/01/2012
... 30/01/2012""")
>>> 
>>> pd.read_csv(s, parse_dates=[0], dayfirst=True)
                 date
0 2012-01-12 00:00:00
1 2012-01-12 00:00:00
2 2012-01-30 00:00:00
22
joris

Je pense que vous l'appelez correctement, et j'ai posté ceci comme n problème sur github .

Vous pouvez simplement spécifier le format à to_datetime directement, par exemple:

In [1]: s = pd.Series(['12/1/2012', '30/01/2012'])

In [2]: pd.to_datetime(s, format='%d/%m/%Y')
Out[2]:
0   2012-01-12 00:00:00
1   2012-01-30 00:00:00
dtype: datetime64[ns]

Mise à jour: Comme OP le souligne correctement, cela ne fonctionne pas avec NaN, si vous êtes satisfait de dayfirst=True (qui fonctionne aussi avec NaN):

s.apply(pd.to_datetime, dayfirst=True)

Il convient de noter qu'il faut être prudent en utilisant dayfirst (ce qui est plus facile que de spécifier le format exact), car _ [dayfirst n'est pas strict .

10
Andy Hayden