Comment convertir les dates d'un bloc de données Pandas en un type de données «date»?


104

J'ai une trame de données Pandas, l'une des colonnes contient des chaînes de date au format YYYY-MM-DD

Pour par exemple '2013-10-28'

Au moment où dtypela colonne est object.

Comment convertir les valeurs de colonne au format de date Pandas?

Réponses:


109

Utiliser un type

In [31]: df
Out[31]: 
   a        time
0  1  2013-01-01
1  2  2013-01-02
2  3  2013-01-03

In [32]: df['time'] = df['time'].astype('datetime64[ns]')

In [33]: df
Out[33]: 
   a                time
0  1 2013-01-01 00:00:00
1  2 2013-01-02 00:00:00
2  3 2013-01-03 00:00:00

1
Bien - merci - comment puis-je me débarrasser des 00:00:00 à la fin de chaque date?
user7289

1
L'horodatage des pandas a à la fois la date et l'heure. Voulez-vous dire le convertir en objet de date python?
waitkuo

7
Vous pouvez le convertir pardf['time'] = [time.date() for time in df['time']]
waitkuo

3
que signifie le [ns], pouvez-vous faire de la chaîne de texte une date et supprimer la partie heure de cette date?
yoshiserry

1
@yoshiserry c'est des nanosecondes, et c'est la façon dont les dates sont stockées sous le capot une fois converties correctement (époque en nanosecondes).
Andy Hayden

113

Essentiellement équivalent à @waitingkuo, mais j'utiliserais to_datetimeici (cela semble un peu plus propre et offre des fonctionnalités supplémentaires par exemple dayfirst):

In [11]: df
Out[11]:
   a        time
0  1  2013-01-01
1  2  2013-01-02
2  3  2013-01-03

In [12]: pd.to_datetime(df['time'])
Out[12]:
0   2013-01-01 00:00:00
1   2013-01-02 00:00:00
2   2013-01-03 00:00:00
Name: time, dtype: datetime64[ns]

In [13]: df['time'] = pd.to_datetime(df['time'])

In [14]: df
Out[14]:
   a                time
0  1 2013-01-01 00:00:00
1  2 2013-01-02 00:00:00
2  3 2013-01-03 00:00:00

Manipulation ValueErrors
Si vous vous trouvez dans une situation où

df['time'] = pd.to_datetime(df['time'])

Lance un

ValueError: Unknown string format

Cela signifie que vous avez des valeurs invalides (non coercibles). Si vous êtes d'accord pour les convertir en pd.NaT, vous pouvez ajouter un errors='coerce'argument à to_datetime:

df['time'] = pd.to_datetime(df['time'], errors='coerce')

Salut les gars, @AndyHayden pouvez-vous supprimer la partie horaire de la date? Je n'ai pas besoin de cette partie?
yoshiserry

Dans la version 0.13.1 de pandas, les 00: 00: 00 de fin ne sont pas affichés.
Andy Hayden

et qu'en est-il des autres versions, comment les supprimer / et ou ne pas les afficher?
yoshiserry

Je ne pense pas que cela puisse être fait d'une manière agréable, il y a une discussion pour ajouter date_format comme float_format (que vous avez vu). Je recommande la mise à niveau de toute façon.
Andy Hayden

mon problème est que ma date est dans ce format ... 41516.43, et j'obtiens cette erreur. Je m'attendrais à ce qu'il retourne quelque chose comme 2014-02-03 dans la nouvelle colonne?! L'ERREUR: #convertir les valeurs de date de la colonne "load_date" en dates budget_dataset ['date_last_load'] = pd.to_datetime (budget_dataset ['load_date']) budget_dataset -c: 2: SettingWithCopyWarning: Une valeur essaie d'être définie sur un copie d'une tranche d'un DataFrame. Essayez d'utiliser .loc [row_index, col_indexer] = value à la place
yoshiserry

35

J'imagine que beaucoup de données arrivent dans Pandas à partir de fichiers CSV, auquel cas vous pouvez simplement convertir la date lors de la lecture initiale du CSV:

dfcsv = pd.read_csv('xyz.csv', parse_dates=[0])où le 0 fait référence à la colonne dans laquelle se trouve la date.
Vous pouvez également y ajouter , index_col=0si vous voulez que la date soit votre index.

Voir https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.read_csv.html


Merci, c'était exactement ce dont j'avais besoin. La documentation a changé, cependant, vous pouvez la trouver ici: pandas.pydata.org/pandas-docs/stable/reference/api/…
Sastibe le

24

Maintenant tu peux faire df['column'].dt.date

Notez que pour les objets datetime, si vous ne voyez pas l'heure à laquelle ils sont tous 00:00:00, ce ne sont pas des pandas. C'est un cahier iPython qui essaie de rendre les choses jolies.


2
Celui-ci ne fonctionne pas pour moi, il se plaint: ne peut utiliser que l'accesseur .dt avec des valeurs datetimelike
smishra

2
vous devrez peut-être d' df[col] = pd.to_datetime(df[col])abord convertir votre colonne en objets de date et d'heure.
szeitlin

Le problème avec cette réponse est qu'elle convertit la colonne dans dtype = objectlaquelle prend beaucoup plus de mémoire qu'un vrai datetime dtypechez les pandas.
elPastor

6

Une autre façon de faire ceci et cela fonctionne bien si vous avez plusieurs colonnes à convertir en datetime.

cols = ['date1','date2']
df[cols] = df[cols].apply(pd.to_datetime)

Question demandez la date et non la date / heure.
Mark Andersen

@MarkAndersen tant que vous n'avez dateque des valeurs dans vos colonnes, la conversion en datetime conservera uniquement les informations pertinentes . Si vous convertissez explicitement en utilisant df['datetime_col'].dt.datecela se traduira par un objectdtype; perte de gestion de la mémoire.
Sumanth Lazarus


1

Il se peut que les dates doivent être converties à une fréquence différente. Dans ce cas, je suggérerais de définir un index par dates.

#set an index by dates
df.set_index(['time'], drop=True, inplace=True)

Après cela, vous pouvez plus facilement convertir le type de format de date dont vous aurez le plus besoin. Ci-dessous, je convertis séquentiellement en un certain nombre de formats de date, pour finalement aboutir à un ensemble de dates quotidiennes au début du mois.

#Convert to daily dates
df.index = pd.DatetimeIndex(data=df.index)

#Convert to monthly dates
df.index = df.index.to_period(freq='M')

#Convert to strings
df.index = df.index.strftime('%Y-%m')

#Convert to daily dates
df.index = pd.DatetimeIndex(data=df.index)

Par souci de concision, je ne montre pas que j'exécute le code suivant après chaque ligne ci-dessus:

print(df.index)
print(df.index.dtype)
print(type(df.index))

Cela me donne la sortie suivante:

Index(['2013-01-01', '2013-01-02', '2013-01-03'], dtype='object', name='time')
object
<class 'pandas.core.indexes.base.Index'>

DatetimeIndex(['2013-01-01', '2013-01-02', '2013-01-03'], dtype='datetime64[ns]', name='time', freq=None)
datetime64[ns]
<class 'pandas.core.indexes.datetimes.DatetimeIndex'>

PeriodIndex(['2013-01', '2013-01', '2013-01'], dtype='period[M]', name='time', freq='M')
period[M]
<class 'pandas.core.indexes.period.PeriodIndex'>

Index(['2013-01', '2013-01', '2013-01'], dtype='object')
object
<class 'pandas.core.indexes.base.Index'>

DatetimeIndex(['2013-01-01', '2013-01-01', '2013-01-01'], dtype='datetime64[ns]', freq=None)
datetime64[ns]
<class 'pandas.core.indexes.datetimes.DatetimeIndex'>

0

Essayez de convertir l'une des lignes en horodatage à l'aide de la fonction pd.to_datetime, puis utilisez .map pour mapper le formulaire à la colonne entière


0
 #   Column          Non-Null Count   Dtype         
---  ------          --------------   -----         
 0   startDay        110526 non-null  object
 1   endDay          110526 non-null  object

import pandas as pd

df['startDay'] = pd.to_datetime(df.startDay)

df['endDay'] = pd.to_datetime(df.endDay)

 #   Column          Non-Null Count   Dtype         
---  ------          --------------   -----         
 0   startDay        110526 non-null  datetime64[ns]
 1   endDay          110526 non-null  datetime64[ns]

0

Par souci d'exhaustivité, une autre option, qui n'est peut-être pas la plus simple, un peu similaire à celle proposée par @SSS, mais en utilisant plutôt la bibliothèque datetime est:

import datetime
df["Date"] = df["Date"].apply(lambda x: datetime.datetime.strptime(x, '%Y-%d-%m').date())
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.