102 votes

Comment convertir des colonnes en une seule colonne de date et heure dans pandas?

J'ai un dataframe où les 3 premières colonnes sont 'MOIS', 'JOUR', 'ANNÉE'

Dans chaque colonne il y a un entier. Y a-t-il un moyen pythonique de convertir les trois colonnes en datetimes alors qu'elles sont dans le dataframe?

De:

M    D    Y    Pommes   Oranges
5    6  1990      12        3
5    7  1990      14        4
5    8  1990      15       34
5    9  1990      23       21

en:

Datetimes    Pommes   Oranges
1990-6-5        12        3
1990-7-5        14        4
1990-8-5        15       34
1990-9-5        23       21

147voto

jezrael Points 290608

Dans la version 0.18.1, vous pouvez utiliser to_datetime, mais :

  • Les noms des colonnes doivent être year, month, day, hour, minute et second :
  • Les colonnes minimales sont year, month et day

Exemple:

import pandas as pd

df = pd.DataFrame({'year': [2015, 2016],
                   'month': [2, 3],
                    'day': [4, 5],
                    'hour': [2, 3],
                    'minute': [10, 30],
                    'second': [21,25]})

print df
   day  hour  minute  month  second  year
0    4     2      10      2      21  2015
1    5     3      30      3      25  2016

print pd.to_datetime(df[['year', 'month', 'day']])
0   2015-02-04
1   2016-03-05
dtype: datetime64[ns]

print pd.to_datetime(df[['year', 'month', 'day', 'hour']])
0   2015-02-04 02:00:00
1   2016-03-05 03:00:00
dtype: datetime64[ns]

print pd.to_datetime(df[['year', 'month', 'day', 'hour', 'minute']])
0   2015-02-04 02:10:00
1   2016-03-05 03:30:00
dtype: datetime64[ns]

print pd.to_datetime(df)
0   2015-02-04 02:10:21
1   2016-03-05 03:30:25
dtype: datetime64[ns]

Une autre solution est de convertir en dictionnaire :

print df
   M  D     Y  Apples  Oranges
0  5  6  1990      12        3
1  5  7  1990      14        4
2  5  8  1990      15       34
3  5  9  1990      23       21

print pd.to_datetime(dict(year=df.Y, month=df.M, day=df.D))
0   1990-05-06
1   1990-05-07
2   1990-05-08
3   1990-05-09
dtype: datetime64[ns]

71voto

Jeff Points 27612

En 0.13 (arrivant très bientôt), c'est fortement optimisé et assez rapide (mais toujours assez rapide en 0.12); deux ordres de grandeur plus rapide que la boucle

In [3]: df
Out[3]: 
   M  D     Y  Apples  Oranges
0  5  6  1990      12        3
1  5  7  1990      14        4
2  5  8  1990      15       34
3  5  9  1990      23       21

In [4]: df.dtypes
Out[4]: 
M          int64
D          int64
Y          int64
Apples     int64
Oranges    int64
dtype: object

# en 0.12, utilisez ceci
In [5]: pd.to_datetime((df.Y*10000+df.M*100+df.D).apply(str),format='%Y%m%d')

# en 0.13 ce qui précède ou cela fonctionnera
In [5]: pd.to_datetime(df.Y*10000+df.M*100+df.D,format='%Y%m%d')
Out[5]: 
0   1990-05-06 00:00:00
1   1990-05-07 00:00:00
2   1990-05-08 00:00:00
3   1990-05-09 00:00:00
dtype: datetime64[ns]

8voto

unutbu Points 222216

Voici une alternative qui utilise NumPy datetime64 et timedelta64 arithmetic. Il semble être un peu plus rapide pour les petits DataFrames et beaucoup plus rapide pour les plus grands DataFrames:

import numpy as np
import pandas as pd

df = pd.DataFrame({'M':[1,2,3,4], 'D':[6,7,8,9], 'Y':[1990,1991,1992,1993]})
#    D  M     Y
# 0  6  1  1990
# 1  7  2  1991
# 2  8  3  1992
# 3  9  4  1993

y = np.array(df['Y']-1970, dtype='

``

In [214]: df = pd.concat([df]*1000)

In [215]: %timeit pd.to_datetime((df['Y']*10000+df['M']*100+df['D']).astype('int'), format='%Y%m%d')
100 loops, best of 3: 4.87 ms per loop

In [216]: %timeit pd.Series(np.array(df['Y']-1970, dtype='

`

Voici une fonction d'aide pour rendre ceci plus facile à utiliser:

def combine64(years, months=1, days=1, weeks=None, hours=None, minutes=None,
              seconds=None, milliseconds=None, microseconds=None, nanoseconds=None):
    years = np.asarray(years) - 1970
    months = np.asarray(months) - 1
    days = np.asarray(days) - 1
    types = ('

` ``

6voto

user1367204 Points 1315

J'ai repris le problème et je pense avoir trouvé une solution. J'ai initialisé le fichier csv de la manière suivante :

pandas_object = DataFrame(read_csv('/Path/to/csv/file', parse_dates=True, index_col = [2,0,1] ))

Où le :

index_col = [2,0,1]

représente les colonnes [année, mois, jour]

Le seul problème maintenant est que j'ai trois nouvelles colonnes d'index, une représentant l'année, une autre le mois et une autre le jour.

2voto

Q-man Points 573

Convertissez le dataframe en chaînes de caractères pour faciliter la concaténation des chaînes :

df=df.astype(str)

puis convertissez en datetime, spécifiez le format :

df.index=pd.to_datetime(df.Y+df.M+df.D,format="%Y%m%d")

ce qui remplace l'index plutôt que de créer une nouvelle colonne.

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