Conversion entre datetime, Timestamp et datetime64

comment convertir un objet numpy.datetime64 en un objet datetime.datetime (ou Timestamp )?

dans le code suivant, je crée des objets datetime, timestamp et datetime64.

import datetime
import numpy as np
import pandas as pd
dt = datetime.datetime(2012, 5, 1)
# A strange way to extract a Timestamp object, there's surely a better way?
ts = pd.DatetimeIndex([dt])[0]
dt64 = np.datetime64(dt)

In [7]: dt
Out[7]: datetime.datetime(2012, 5, 1, 0, 0)

In [8]: ts
Out[8]: <Timestamp: 2012-05-01 00:00:00>

In [9]: dt64
Out[9]: numpy.datetime64('2012-05-01T01:00:00.000000+0100')

Note: il est facile d'obtenir le datetime à partir de L'horodatage:

In [10]: ts.to_datetime()
Out[10]: datetime.datetime(2012, 5, 1, 0, 0)

mais comment extraire le datetime ou Timestamp d'un numpy.datetime64 ( dt64 )?

.

mise à Jour: un peu méchant exemple dans ma base de données (peut-être la motivation exemple) semble être:

dt64 = numpy.datetime64('2002-06-28T01:00:00.000000000+0100')

qui devrait être datetime.datetime(2002, 6, 28, 1, 0) , et pas un long (!) ( 1025222400000000000L )...

195
demandé sur Andy Hayden 2012-12-04 17:08:29

12 réponses

pour convertir numpy.datetime64 en objet datetime qui représente le temps en TUC sur numpy-1.8 :

>>> from datetime import datetime
>>> import numpy as np
>>> dt = datetime.utcnow()
>>> dt
datetime.datetime(2012, 12, 4, 19, 51, 25, 362455)
>>> dt64 = np.datetime64(dt)
>>> ts = (dt64 - np.datetime64('1970-01-01T00:00:00Z')) / np.timedelta64(1, 's')
>>> ts
1354650685.3624549
>>> datetime.utcfromtimestamp(ts)
datetime.datetime(2012, 12, 4, 19, 51, 25, 362455)
>>> np.__version__
'1.8.0.dev-7b75899'

l'exemple ci-dessus suppose qu'un objet datetime naïf est interprété par np.datetime64 comme du temps en TUC.


pour convertir datetime en np.datetime64 et retour ( numpy-1.6 ):

>>> np.datetime64(datetime.utcnow()).astype(datetime)
datetime.datetime(2012, 12, 4, 13, 34, 52, 827542)

il fonctionne à la fois sur un seul np.objet datetime64 et un tableau numpy de np.datetime64.

pensez à np.datetime64 de la même façon que vous le feriez pour np.int8, np.int16, etc. et appliquent les mêmes méthodes pour convertir des objets Python comme int, datetime et les objets numpy correspondants.

votre "mauvais exemple" fonctionne correctement:

>>> from datetime import datetime
>>> import numpy 
>>> numpy.datetime64('2002-06-28T01:00:00.000000000+0100').astype(datetime)
datetime.datetime(2002, 6, 28, 0, 0)
>>> numpy.__version__
'1.6.2' # current version available via pip install numpy

je peux reproduire la valeur long sur numpy-1.8.0 installé comme:

pip install git+https://github.com/numpy/numpy.git#egg=numpy-dev

le même exemple:

>>> from datetime import datetime
>>> import numpy
>>> numpy.datetime64('2002-06-28T01:00:00.000000000+0100').astype(datetime)
1025222400000000000L
>>> numpy.__version__
'1.8.0.dev-7b75899'

retourne long parce que pour numpy.datetime64 type .astype(datetime) est équivalent à .astype(object) qui renvoie Python entier ( long ) sur numpy-1.8 .

pour obtenir l'objet datetime vous pouvez:

>>> dt64.dtype
dtype('<M8[ns]')
>>> ns = 1e-9 # number of seconds in a nanosecond
>>> datetime.utcfromtimestamp(dt64.astype(int) * ns)
datetime.datetime(2002, 6, 28, 0, 0)

pour obtenir datetime64 qui utilise les secondes directement:

>>> dt64 = numpy.datetime64('2002-06-28T01:00:00.000000000+0100', 's')
>>> dt64.dtype
dtype('<M8[s]')
>>> datetime.utcfromtimestamp(dt64.astype(int))
datetime.datetime(2002, 6, 28, 0, 0)

le num PY docs disent que l'API datetime est expérimentale et peut changer en futures versions de numpy.

95
répondu jfs 2012-12-04 20:30:33

vous pouvez utiliser la police.Constructeur de Timestamp. Le diagramme ci-dessous peut être utile pour répondre à cette question et à d'autres questions connexes.

Conversions between time representations

147
répondu Quant 2014-02-20 18:17:06

bienvenue en enfer.

vous pouvez simplement passer un objet datetime64 à pandas.Timestamp :

In [16]: Timestamp(numpy.datetime64('2012-05-01T01:00:00.000000'))
Out[16]: <Timestamp: 2012-05-01 01:00:00>

j'ai remarqué que cela ne fonctionne pas bien même dans NumPy 1.6.1:

numpy.datetime64('2012-05-01T01:00:00.000000+0100')

aussi, pandas.to_datetime peut être utilisé (ceci est hors de la version dev, n'ont pas coché v0.9.1):

In [24]: pandas.to_datetime('2012-05-01T01:00:00.000000+0100')
Out[24]: datetime.datetime(2012, 5, 1, 1, 0, tzinfo=tzoffset(None, 3600))
100
répondu Wes McKinney 2012-12-06 22:40:22

je pense qu'il pourrait y avoir un effort plus consolidé dans une réponse pour mieux expliquer la relation entre le module datetime de Python, les objets datetime64/timedelta64 de num Python et les objets Timestamp/Timedelta de pandas.

datetime bibliothèque standard de Python

datetime de la bibliothèque standard a quatre principaux objets

  • temps - seul le temps, mesuré en heures, minutes, secondes et microsecondes
  • date-only année, mois et jour
  • datetime - Tous les composants de l'heure et de la date
  • timedelta - Un montant de temps le maximum de l'unité de jours

la création de ces quatre objets

>>> import datetime
>>> datetime.time(hour=4, minute=3, second=10, microsecond=7199)
datetime.time(4, 3, 10, 7199)

>>> datetime.date(year=2017, month=10, day=24)
datetime.date(2017, 10, 24)

>>> datetime.datetime(year=2017, month=10, day=24, hour=4, minute=3, second=10, microsecond=7199)
datetime.datetime(2017, 10, 24, 4, 3, 10, 7199)

>>> datetime.timedelta(days=3, minutes = 55)
datetime.timedelta(3, 3300)

>>> # add timedelta to datetime
>>> datetime.timedelta(days=3, minutes = 55) + \
    datetime.datetime(year=2017, month=10, day=24, hour=4, minute=3, second=10, microsecond=7199)
datetime.datetime(2017, 10, 27, 4, 58, 10, 7199)

NumPy est datetime64 et timedelta64 objets

NumPy n'a pas d'objets date et time séparés, juste un seul objet datetime64 pour représenter un seul moment dans le temps. L'objet datetime du module datetime a une précision de microseconde (un millionième de seconde). L'objet datetime64 de num PY vous permet de régler sa précision des heures jusqu'aux attosecondes (10 ^ -18). Son constructeur est plus flexible et peut prendre une variété d'entrées.

Construire NumPy est datetime64 et timedelta64 objets

passe un entier avec une chaîne pour les unités. voir toutes les unités ici . Il est converti que de nombreuses unités après L'époque UNIX: 1er janvier 1970

>>> np.datetime64(5, 'ns') 
numpy.datetime64('1970-01-01T00:00:00.000000005')

>>> np.datetime64(1508887504, 's')
numpy.datetime64('2017-10-24T23:25:04')

vous pouvez également utiliser des chaînes aussi longtemps qu'elles sont au format ISO 8601.

>>> np.datetime64('2017-10-24')
numpy.datetime64('2017-10-24')

Timedeltas ont une seule unité

>>> np.timedelta64(5, 'D') # 5 days
>>> np.timedelta64(10, 'h') 10 hours

peut aussi les créer en soustrayant deux objets datetime64

>>> np.datetime64('2017-10-24T05:30:45.67') - np.datetime64('2017-10-22T12:35:40.123')
numpy.timedelta64(147305547,'ms')

Pandas Timestamp et Timedelta construire beaucoup plus de fonctionnalités sur le dessus de NumPy

Une pandas Timestamp est un moment très similaire à un datetime, mais avec beaucoup plus de fonctionnalités. Vous pouvez les construire avec pd.Timestamp ou pd.to_datetime .

>>> pd.Timestamp(1239.1238934) #defautls to nanoseconds
Timestamp('1970-01-01 00:00:00.000001239')

>>> pd.Timestamp(1239.1238934, unit='D') # change units
Timestamp('1973-05-24 02:58:24.355200')

>>> pd.Timestamp('2017-10-24 05') # partial strings work
Timestamp('2017-10-24 05:00:00')

pd.to_datetime fonctionne de manière très similaire (avec quelques options supplémentaires) et peut convertir une liste de chaînes en horodateurs.

>>> pd.to_datetime('2017-10-24 05')
Timestamp('2017-10-24 05:00:00')

>>> pd.to_datetime(['2017-1-1', '2017-1-2'])
DatetimeIndex(['2017-01-01', '2017-01-02'], dtype='datetime64[ns]', freq=None)

conversion de Python datetime en datetime64 et Timestamp

>>> dt = datetime.datetime(year=2017, month=10, day=24, hour=4, 
                   minute=3, second=10, microsecond=7199)
>>> np.datetime64(dt)
numpy.datetime64('2017-10-24T04:03:10.007199')

>>> pd.Timestamp(dt) # or pd.to_datetime(dt)
Timestamp('2017-10-24 04:03:10.007199')

la Conversion de numpy datetime64 à DateTime et horodatage

>>> dt64 = np.datetime64('2017-10-24 05:34:20.123456')
>>> unix_epoch = np.datetime64(0, 's')
>>> one_second = np.timedelta64(1, 's')
>>> seconds_since_epoch = (dt64 - unix_epoch) / one_second
>>> seconds_since_epoch
1508823260.123456

>>> datetime.datetime.utcfromtimestamp(seconds_since_epoch)
>>> datetime.datetime(2017, 10, 24, 5, 34, 20, 123456)

Convertir un Timestamp

>>> pd.Timestamp(dt64)
Timestamp('2017-10-24 05:34:20.123456')

Convertir à partir d'Horodatage date / heure et datetime64

c'est assez facile car les pointeurs de pandas sont très puissants

>>> ts = pd.Timestamp('2017-10-24 04:24:33.654321')

>>> ts.to_pydatetime()   # Python's datetime
datetime.datetime(2017, 10, 24, 4, 24, 33, 654321)

>>> ts.to_datetime64()
numpy.datetime64('2017-10-24T04:24:33.654321000')
41
répondu Ted Petrou 2018-06-19 14:48:53
>>> dt64.tolist()
datetime.datetime(2012, 5, 1, 0, 0)

Pour DatetimeIndex , le tolist renvoie une liste de datetime des objets. Pour un seul objet datetime64 , il renvoie un seul objet datetime .

24
répondu eumiro 2012-12-04 13:22:10

si vous voulez convertir une série entière de pandas en Python, vous pouvez aussi utiliser .to_pydatetime() .

pd.date_range('20110101','20110102',freq='H').to_pydatetime()

> [datetime.datetime(2011, 1, 1, 0, 0) datetime.datetime(2011, 1, 1, 1, 0)
   datetime.datetime(2011, 1, 1, 2, 0) datetime.datetime(2011, 1, 1, 3, 0)
   ....

il supporte aussi timezones:

pd.date_range('20110101','20110102',freq='H').tz_localize('UTC').tz_convert('Australia/Sydney').to_pydatetime()

[ datetime.datetime(2011, 1, 1, 11, 0, tzinfo=<DstTzInfo 'Australia/Sydney' EST+11:00:00 DST>)
 datetime.datetime(2011, 1, 1, 12, 0, tzinfo=<DstTzInfo 'Australia/Sydney' EST+11:00:00 DST>)
....
8
répondu fantabolous 2014-08-15 09:41:31

une option est d'utiliser str , puis to_datetime (ou similaire):

In [11]: str(dt64)
Out[11]: '2012-05-01T01:00:00.000000+0100'

In [12]: pd.to_datetime(str(dt64))
Out[12]: datetime.datetime(2012, 5, 1, 1, 0, tzinfo=tzoffset(None, 3600))

Remarque: il n'est pas égal à dt parce qu'il est devenu "le décalage de courant" :

In [13]: pd.to_datetime(str(dt64)).replace(tzinfo=None)
Out[13]: datetime.datetime(2012, 5, 1, 1, 0)

cela semble inélégant.

.

mise à jour: cela peut traiter du "mauvais exemple":

In [21]: dt64 = numpy.datetime64('2002-06-28T01:00:00.000000000+0100')

In [22]: pd.to_datetime(str(dt64)).replace(tzinfo=None)
Out[22]: datetime.datetime(2002, 6, 28, 1, 0)
7
répondu Andy Hayden 2017-05-23 12:02:48

ce poste est en place depuis 4 ans et j'ai encore lutté avec ce problème de conversion - donc la question est toujours active en 2017 dans un certain sens. J'ai été quelque peu choqué que la documentation de numpy n'offre pas facilement un algorithme de conversion simple, mais c'est une autre histoire.

j'ai rencontré une autre façon de faire la conversion qui ne concerne que les modules numpy et datetime , il ne nécessite pas pandas à importer qui me semble être beaucoup de code à importer pour une conversion aussi simple. J'ai remarqué que datetime64.astype(datetime.datetime) retournera un datetime.datetime objet si l'original datetime64 est dans micro-unités de seconde tandis que d'autres unités renvoient un timestamp entier. J'utilise le module xarray pour les données e/s des fichiers Netcdf qui utilise le datetime64 en unités nanosecondes faisant échouer la conversion sauf si vous convertissez d'abord en unités micro-secondes. Voici l'exemple de code de conversion,

import numpy as np
import datetime

def convert_datetime64_to_datetime( usert: np.datetime64 )->datetime.datetime:
    t = np.datetime64( usert, 'us').astype(datetime.datetime)
return t

est le seul testé sur ma machine, qui est Python 3.6 avec une récente distribution anaconda 2017. J'ai seulement regardé la conversion scalaire et n'ai pas vérifié les conversions basées sur les tableaux bien que je devine qu'il sera bon. Je n'ai pas non plus regardé le code source de numpy datetime64 pour voir si l'opération avait un sens ou non.

3
répondu ndl303 2017-10-13 11:01:25

je suis revenu à cette réponse plus de fois que je ne peux compter, donc j'ai décidé de jeter ensemble une petite classe rapide, qui convertit une valeur" Numpy datetime64 à la valeur "Python datetime . J'espère que cela aidera d'autres.

from datetime import datetime
import pandas as pd

class NumpyConverter(object):
    @classmethod
    def to_datetime(cls, dt64, tzinfo=None):
        """
        Converts a Numpy datetime64 to a Python datetime.
        :param dt64: A Numpy datetime64 variable
        :type dt64: numpy.datetime64
        :param tzinfo: The timezone the date / time value is in
        :type tzinfo: pytz.timezone
        :return: A Python datetime variable
        :rtype: datetime
        """
        ts = pd.to_datetime(dt64)
        if tzinfo is not None:
            return datetime(ts.year, ts.month, ts.day, ts.hour, ts.minute, ts.second, tzinfo=tzinfo)
        return datetime(ts.year, ts.month, ts.day, ts.hour, ts.minute, ts.second)

je vais garder ça dans mon sac à outils, quelque chose me dit que j'en aurai encore besoin.

1
répondu MikeyE 2017-08-02 06:59:32

en effet, tous ces types de datetime peuvent être difficiles, et potentiellement problématiques (doit garder une trace attentive des informations de fuseau horaire). voici ce que j'ai fait, même si je reconnais que je suis préoccupé qu'au moins une partie de celui-ci est "pas par la conception". en outre, cela peut être fait un peu plus compact que nécessaire. en commençant par un numpy.datetime64 dt_a:

dt_a

numpy.datetime64 ('2015-04-24T23:11:26.270000-0700')

dt_a1 = dt_a.tolist () # fournit un objet datetime dans UTC, mais sans tzinfo

dt_a1

datetime.datetime(2015, 4, 25, 6, 11, 26, 270000)

# now, make your "aware" datetime:

dt_a2=datetime.datetime(*liste(dt_a1.timetuple()[:6]) + [dt_a1.microseconde], tzinfo=pytz.le fuseau horaire('UTC'))

... et bien sûr, cela peut être compressé en un seul ligne si nécessaire.

0
répondu yoder 2015-08-04 18:37:14
import numpy as np
import pandas as pd 

def np64toDate(np64):
    return pd.to_datetime(str(np64)).replace(tzinfo=None).to_datetime()

utilisez cette fonction pour obtenir l'objet datetime natif de pythons

0
répondu Crystal 2016-06-05 16:04:56

Certaines solutions fonctionnent bien pour moi, mais numpy va déprécier certains paramètres. La solution qui fonctionne mieux pour moi est de lire la date comme une datetime pandas et d'exclure explicitement l'année, le mois et le jour d'un objet pandas. Le code suivant fonctionne pour la situation la plus courante.

def format_dates(dates):
    dt = pd.to_datetime(dates)
    try: return [datetime.date(x.year, x.month, x.day) for x in dt]    
    except TypeError: return datetime.date(dt.year, dt.month, dt.day)
0
répondu João Gabriel John 2018-03-22 16:58:16