web-dev-qa-db-fra.com

Pandas conversion de ligne avec horodatage unix (en millisecondes) en datetime

J'ai besoin de traiter une énorme quantité de fichiers CSV où l'horodatage est toujours une chaîne représentant l'horodatage Unix en millisecondes. Je n'ai pas encore trouvé de méthode pour modifier ces colonnes efficacement.

C'est ce que j'ai trouvé, mais cela ne fait bien sûr que dupliquer la colonne et je dois en quelque sorte la remettre dans le jeu de données d'origine. Je suis sûr que cela peut être fait lors de la création du DataFrame?

import sys
if sys.version_info[0] < 3:
    from StringIO import StringIO
else:
    from io import StringIO
import pandas as pd

data = 'RUN,UNIXTIME,VALUE\n1,1447160702320,10\n2,1447160702364,20\n3,1447160722364,42'

df = pd.read_csv(StringIO(data))

convert = lambda x: datetime.datetime.fromtimestamp(x / 1e3)
converted_df = df['UNIXTIME'].apply(convert)

Cela va choisir la colonne 'UNIXTIME' et la changer de

0    1447160702320
1    1447160702364
2    1447160722364
Name: UNIXTIME, dtype: int64

dans ce

0   2015-11-10 14:05:02.320
1   2015-11-10 14:05:02.364
2   2015-11-10 14:05:22.364
Name: UNIXTIME, dtype: datetime64[ns]

Cependant, je voudrais utiliser quelque chose comme pd.apply() pour obtenir l'ensemble de données retourné avec la colonne convertie ou, comme je l'ai déjà écrit, créer simplement des heures lors de la génération du DataFrame à partir de CSV.

27
tamasgal

Vous pouvez le faire comme une étape de post-traitement en utilisant to_datetime et en passant arg unit='ms':

In [5]:
df['UNIXTIME'] = pd.to_datetime(df['UNIXTIME'], unit='ms')
df

Out[5]:
   RUN                UNIXTIME  VALUE
0    1 2015-11-10 13:05:02.320     10
1    2 2015-11-10 13:05:02.364     20
2    3 2015-11-10 13:05:22.364     42
33
EdChum

J'utilise la solution @EdChum, mais j'ajoute la gestion du fuseau horaire:

df['UNIXTIME']=pd.DatetimeIndex(pd.to_datetime(pd['UNIXTIME'], unit='ms'))\
                 .tz_localize('UTC' )\
                 .tz_convert('America/New_York')

le tz_localize indique que l'horodatage doit être considéré comme concernant 'UTC', puis le tz_convert déplace en fait la date/l'heure vers le fuseau horaire correct (dans ce cas, "America/New_York").

Notez qu'il a été converti en DatetimeIndex car le tz_ Les méthodes ne fonctionnent que sur l'index de la série. Depuis Pandas 0,15 on peut utiliser .dt:

df['UNIXTIME']=pd.to_datetime(pd['UNIXTIME'], unit='ms')\
                 .dt.tz_localize('UTC' )\
                 .dt.tz_convert('America/New_York')
6
Teudimundo

J'ai trouvé une solution, je suppose:

convert = lambda x: datetime.datetime.fromtimestamp(float(x) / 1e3)

df = pd.read_csv(StringIO(data), parse_dates=['UNIXTIME'], date_parser=convert)

Je ne sais toujours pas si c'est le meilleur.

2
tamasgal

si vous connaissez l'unité d'horodatage, utilisez Series.astype:

df['UNIXTIME'].astype('datetime64[ms]')

0   2015-11-10 13:05:02.320
1   2015-11-10 13:05:02.364
2   2015-11-10 13:05:22.364
Name: UNIXTIME, dtype: datetime64[ns]

Pour renvoyer l'intégralité du DataFrame, utilisez

df.astype({'UNIXTIME': 'datetime64[ms]'})

   RUN                UNIXTIME  VALUE
0    1 2015-11-10 13:05:02.320     10
1    2 2015-11-10 13:05:02.364     20
2    3 2015-11-10 13:05:22.364     42
1
cs95