在date时间,时间戳和date时间64之间转换

如何将numpy.datetime64对象转换为datetime.datetime (或Timestamp )?

在下面的代码中,我创build了一个datetime,timestamp和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') 

注意:从时间戳中很容易得到date时间:

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

但是,我们如何从numpy.datetime64dt64 )提取datetime TimestampTimestamp呢?

更新:我的数据集中的一个有点令人讨厌的例子(也许是激励的例子)似乎是:

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

这应该是datetime.datetime(2002, 6, 28, 1, 0) 1025222400000000000L ),而不是一个长(!)( 1025222400000000000L )…

要将numpy.datetime64转换numpy.datetime64numpy-1.8表示UTC时间的datetime对象:

 >>> 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' 

上面的例子假定一个天真的date时间对象被np.datetime64解释为UTC的时间。


将datetime转换为np.datetime64并返回( numpy-1.6 ):

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

它既可以在单个np.datetime64对象上运行,也可以在np.datetime64的numpy数组上运行。

想想np.datetime64就像np.int8,np.int16等一样,并应用相同的方法来转换Python对象(如int,datetime和相应的numpy对象)之间的相互作用。

你的“令人讨厌的例子”正常工作:

 >>> 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 

我可以重现在numpy-1.8.0long价值安装为:

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

同样的例子:

 >>> 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' 

它返回long因为对于numpy.datetime64types.astype(datetime)等同于.astype(object) ,在numpy-1.8上返回Python整数( long )。

要获取date时间对象,您可以:

 >>> 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) 

要直接获取使用秒的datetime64:

 >>> 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) 

numpy文档说datetime API是实验性的,可能会在未来的numpy版本中改变。

你可以使用pd.Timestamp构造函数。 下图对这个和相关的问题可能是有用的。

时间表示之间的转换

欢迎来到地狱。

你可以传递一个datetime64对象给pandas.Timestamp

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

我注意到这在NumPy 1.6.1中并不适用:

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

此外,可以使用pandas.to_datetime (这是closuresdev版本,没有检查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)) 
 >>> dt64.tolist() datetime.datetime(2012, 5, 1, 0, 0) 

对于DatetimeIndextolist返回一个datetime对象的列表。 对于单个datetime64对象,它返回一个单独的datetime对象。

一个select是使用str ,然后to_datetime (或类似):

 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)) 

注意:它不等于dt因为它变成了“偏移感知” :

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

这似乎不雅。

更新:这可以处理“讨厌的例子”:

 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) 

如果你想把整个pandas系列的date时间转换成普通的Pythondate时间,你也可以使用.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) .... 

它也支持时区:

 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>) .... 

我认为在更好地解释Python的date时间模块,numpy的datetime64 / timedelta64和pandas的Timestamp / Timedelta对象之间的关系方面,可能会有一个更加巩固的努力。

Python的date时间标准库

date时间标准库有四个主要对象

  • 只有时间,以小时,分,秒和微秒为单位
  • date – 只有年,月和日
  • datetime – 时间和date的所有组件
  • timedelta – 最大单位天数的时间量

创build这四个对象

 >>> 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的datetime64和timedelta64对象

NumPy没有单独的date和时间对象,只有一个datetime64对象来表示一个时刻。 date时间模块的date时间对象具有微秒精度(百万分之一秒)。 NumPy的datetime64对象具有纳秒精度。 它的构造更灵活,可以采取各种input。

构buildNumPy的datetime64和timedelta64对象

用单位的string传递一个整数。 在这里查看所有单位 。 在UNIX纪元1970年1月1日之后,它被转换为许多单位

 >>> np.datetime64(5, 'ns') numpy.datetime64('1970-01-01T00:00:00.000000005') >>> np.datetime64(1508887504, 's') numpy.datetime64('2017-10-24T23:25:04') 

只要符合ISO 8601格式,您也可以使用string。

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

Timedeltas有一个单位

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

也可以通过减去两个datetime64对象来创build它们

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

pandasTimestamp和Timedelta在NumPy之上构build了更多的function

pandas时间戳是一个非常类似于date时间的时刻,但function更多。 您可以使用pd.Timestamppd.to_datetime来构build它们。

 >>> 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工作方式非常相似(有几个选项),并可以将string列表转换为时间戳。

 >>> 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) 

将Pythondate时间转换为datetime64和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') 

将numpy datetime64转换为datetime和Timestamp

 >>> 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) 

转换为时间戳

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

从时间戳转换为date时间和date时间64

这是非常容易的,因为pandas时间戳非常强大

 >>> 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') 

事实上,所有这些date时间types都可能是困难的,并且可能有问题(必须仔细跟踪时区信息)。 这是我所做的,尽pipe我承认我担心至less有一部分是“不按devise”。 而且,根据需要,这可以变得更紧凑。 从numpy.datetime64 dt_a开始:

dt_a

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

dt_a1 = dt_a.tolist()#以UTCforms产生一个date时间对象,但没有tzinfo

dt_a1

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

 # now, make your "aware" datetime: 

dt_a2 = datetime.datetime(* list(dt_a1.timetuple()[:6])+ [dt_a1.microsecond],tzinfo = pytz.timezone('UTC'))

…当然,可以根据需要压缩成一行。

 import numpy as np import pandas as pd def np64toDate(np64): return pd.to_datetime(str(np64)).replace(tzinfo=None).to_datetime() 

使用这个函数来获取python本地date时间对象

我已经回到这个答案的次数了,所以我决定抛出一个快速的小class,将Numpy datetime64值转换为Python datetime值。 我希望它能帮助别人。

 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) 

我要把它放在我的工具包里,有一些东西告诉我我会再次需要它。

这篇文章已经有四年的时间了,我还在为这个转换问题而苦苦挣扎,所以从某种意义上说,这个问题在2017年还是有效的。 我有些震惊的是,numpy文档不能提供简单的转换algorithm,但这是另一回事。

我遇到另一种方式来做转换,只涉及模块numpydatetime ,它并不需要导入大pandas,这似乎是很多代码导入这样一个简单的转换。 我注意到, datetime64.astype(datetime.datetime)将返回一个datetime.datetime对象,如果原始的datetime64是在微秒单位,而其他单位返回一个整数时间戳。 我使用模块xarray从Netcdf文件的数据I / O使用以纳秒为单位的datetime64 ,使转换失败,除非你首先转换为微秒单位。 这里是示例转换代码,

 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 

它只在我的机器上testing过,这是最近发布的2017年Anaconda发行版Python 3.6。 我只看标量转换,并没有检查基于数组的转换,虽然我猜这将是好事。 我也没有看过numpy datetime64源代码来查看操作是否合理。