在datetime,Timestamp和datetime64之间转换

And*_*den 256 python datetime numpy pandas

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

在以下代码中,我创建了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')
Run Code Online (Sandbox Code Playgroud)

注意:从时间戳中获取日期时间很容易:

In [10]: ts.to_datetime()
Out[10]: datetime.datetime(2012, 5, 1, 0, 0)
Run Code Online (Sandbox Code Playgroud)

但是我们如何从()中提取datetime或者?Timestampnumpy.datetime64dt64

.

更新:我的数据集(可能是激励示例)中的一个有点讨厌的例子似乎是:

dt64 = numpy.datetime64('2002-06-28T01:00:00.000000000+0100')
Run Code Online (Sandbox Code Playgroud)

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

Qua*_*ant 190

您只需使用pd.Timestamp构造函数即可.以下图表可能对此问题和相关问题有用.

时间表示之间的转换

  • 只要看一下这个图表就会发现,所有这些东西都存在根本性的错误. (74认同)
  • 对于那些略读: `pd.Timestamp()` 将 np.datetime 更改为 pd.Timestamp (6认同)
  • @ Mr.WorshipMe此图需要更新.`pd.to_datetime`将所有内容转换为`pd.Timestamp`.`pd.Timestamp`对象的方法`to_pydatetime`恢复为`datetime.datetime`对象和`to_datetime64`方法转换为`np.datetime64`. (5认同)
  • 我怎样才能获得这张照片的更高分辨率? (5认同)
  • 如果给定ms或ns的数量,pd.to_datetime将生成TimeStamp,但如果给定datetime.datetime,则会生成datetime.datetime,如果给定np.datetime64则会生成np.datetime64,这是非常令人困惑的...为什么会有人认为这是合理的吗? (4认同)
  • 很好!!! (值得一提的是,自从我写了这个问题以来情况已经有所改善,这里已经做了很多工作:)) (2认同)
  • 这个图表需要`string` -&gt; 映射。试试这些:`x = pd.to_datetime('2012-05-01T01:00:00.000000+0100'); 打印(类型(x));print(type(x.to_datetime());`——第一个是`class 'pandas._libs.tslib.Timestamp'`,第二个是`class 'datetime.datetime'`。(你会得到一个警告不推荐使用 `to_datetime()` 用于 `to_pydatetime()`)(在 Pandas 0.22.0 和 Python 3.5.2 中) (2认同)

Wes*_*ney 122

欢迎来到地狱.

您只需将datetime64对象传递给pandas.Timestamp:

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

我注意到这在NumPy 1.6.1中不起作用:

numpy.datetime64('2012-05-01T01:00:00.000000+0100')
Run Code Online (Sandbox Code Playgroud)

另外,pandas.to_datetime可以使用(这是关闭dev版本,还没有检查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))
Run Code Online (Sandbox Code Playgroud)

  • `pd.to_datetime('2012-05-01T01:00:00.000000 + 0100')`至少在pandas`0.17.1`中返回`Timestamp('2012-05-01 00:00:00')`. (6认同)
  • 你应该提到`issubclass(pd.Timestamp,datetime)`是'True`.而`Timestamp`类本身有`to_datetime()`方法. (4认同)

jfs*_*jfs 117

要转换numpy.datetime64为表示UTC时间的datetime对象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'
Run Code Online (Sandbox Code Playgroud)

上面的示例假定一个天真的日期时间对象被解释np.datetime64为UTC中的时间.


要将datetime转换为np.datetime64和back(numpy-1.6):

>>> np.datetime64(datetime.utcnow()).astype(datetime)
datetime.datetime(2012, 12, 4, 13, 34, 52, 827542)
Run Code Online (Sandbox Code Playgroud)

它适用于单个np.datetime64对象和np.datetime64的numpy数组.

可以像np.int8,np.int16等一样考虑np.datetime64,并应用相同的方法来转换Python对象(如int,datetime和相应的numpy对象)之间的beet.

你的"讨厌的例子"正常工作:

>>> 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
Run Code Online (Sandbox Code Playgroud)

我可以将安装的long值重现numpy-1.8.0为:

pip install git+https://github.com/numpy/numpy.git#egg=numpy-dev
Run Code Online (Sandbox Code Playgroud)

同样的例子:

>>> 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'
Run Code Online (Sandbox Code Playgroud)

它返回,long因为numpy.datetime64type .astype(datetime)等效于.astype(object)返回Python integer(long)numpy-1.8.

要获取datetime对象,您可以:

>>> 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)
Run Code Online (Sandbox Code Playgroud)

要获得直接使用秒的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)
Run Code Online (Sandbox Code Playgroud)

numpy的文档说,日期时间API是实验性的,并在未来的版本中numpy的可能改变.

  • 恐怕这似乎并不总是有效:例如`dt64 = numpy.datetime64('2002-06-28T01:00:00.000000000+0100')`,它给出了一个长 (`1025222400000000000L`) ( (2认同)

Ted*_*rou 78

我认为可以在更好地解释Python的datetime模块,numpy的datetime64/timedelta64和pandas的Timestamp/Timedelta对象之间的关系的答案中进行更加整合的努力.

Python的日期时间标准库

datetime标准库有四个主要对象

  • 时间 - 仅限时间,以小时,分钟,秒和微秒为单位
  • 日期 - 仅年,月和日
  • datetime - 时间和日期的所有组成部分
  • timedelta - 最大天数的时间量

创建这四个对象

>>> 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)
Run Code Online (Sandbox Code Playgroud)

NumPy的datetime64和timedelta64对象

NumPy没有单独的日期和时间对象,只有一个datetime64对象来表示单个时刻.datetime模块的datetime对象具有微秒精度(百万分之一秒).NumPy的datetime64对象允许您将其精度从小时数一直设置为阿秒(10 ^ -18).它的构造函数更灵活,可以采用各种输入.

构造NumPy的datetime64和timedelta64对象

传递一个带字符串的整数.在这里查看所有单位.它在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')
Run Code Online (Sandbox Code Playgroud)

您也可以使用字符串,只要它们是ISO 8601格式.

>>> np.datetime64('2017-10-24')
numpy.datetime64('2017-10-24')
Run Code Online (Sandbox Code Playgroud)

Timedeltas有一个单位

>>> np.timedelta64(5, 'D') # 5 days
>>> np.timedelta64(10, 'h') 10 hours
Run Code Online (Sandbox Code Playgroud)

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

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

Pandas Timestamp和Timedelta在NumPy之上构建了更多功能

熊猫时间戳是一个非常类似于日期时间但具有更多功能的时刻.您可与构建它们pd.Timestamppd.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')
Run Code Online (Sandbox Code Playgroud)

pd.to_datetime 工作非常相似(有更多选项),可以将字符串列表转换为时间戳.

>>> 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)
Run Code Online (Sandbox Code Playgroud)

将Python日期时间转换为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')
Run Code Online (Sandbox Code Playgroud)

将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)
Run Code Online (Sandbox Code Playgroud)

转换为时间戳

>>> pd.Timestamp(dt64)
Timestamp('2017-10-24 05:34:20.123456')
Run Code Online (Sandbox Code Playgroud)

从时间戳转换为datetime和datetime64

这很容易,因为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')
Run Code Online (Sandbox Code Playgroud)

  • Numpy 到日期时间。 (3认同)
  • 多么疯狂的约会时间仍然很难// ...难道真的没有更好的方法吗?这是一个很好的答案,我正在考虑接受将其移至顶层,而我必须通过计算机更深入地阅读其他内容。 (2认同)
  • 我认为这是我见过的最好的答案。来自 Excel、VBA、SAS 或 SQL,Python 看起来很奇怪,因为处理日期/时间不只是“一种方法”。与 Python 或 R 中的许多东西一样,似乎必须选择一个最喜欢的方法/模块/类并坚持下去。 (2认同)

eum*_*iro 28

>>> dt64.tolist()
datetime.datetime(2012, 5, 1, 0, 0)
Run Code Online (Sandbox Code Playgroud)

对于DatetimeIndex,tolist返回datetime对象列表.对于单个datetime64对象,它返回单个datetime对象.

  • @hayden如果你知道它是一个标量/ 0-d数组,我宁愿使用更明确的`.item()`(并且没有人会出现并开始争论它应该返回一个列表). (5认同)
  • @hayden:`.item()`返回的类型(由@seberg建议),`.tolist()`取决于datetime64使用的单位,例如,`D`生成`datetime.date()`,`us `(微秒)产生`datetime.datetime()`,`ns`(纳秒)产生`long`.单位根据输入值改变,例如,`numpy.datetime64('2012-05-01')`使用''D'`,`numpy.datetime64('2012-05-01T00:00:00.000')`使用`ms`,`numpy.datetime64('2012-05-01T00:00:00.000000000')`使用`ns`.如果你发现它令人困惑,你可以[打开一个问题](https://github.com/numpy/numpy/issues). (4认同)
  • 恐怕这似乎并不总是有效:例如`dt64 = numpy.datetime64('2002-06-28T01:00:00.000000000+0100')`,它给出了一个长 (`1025222400000000000L`) ( (2认同)

And*_*den 10

一种选择是使用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))
Run Code Online (Sandbox Code Playgroud)

注意:它不等于dt因为它变得"偏移感知":

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

这似乎不优雅.

.

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

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)
Run Code Online (Sandbox Code Playgroud)


fan*_*ous 10

如果你想将整个熊猫系列的日期时间转换为常规的python日期时间,你也可以使用.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)
   ....
Run Code Online (Sandbox Code Playgroud)

它还支持时区:

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>)
....
Run Code Online (Sandbox Code Playgroud)


小智 5

这篇文章已经发表了四年,但我仍在为这个转换问题而苦苦挣扎-因此从某种意义上说,该问题在2017年仍然很活跃。numpy文档没有提供简单的转换算法令我有些震惊,但这是另一回事了。

我遇到了另一种仅涉及模块numpy和的转换方法datetime,它不需要导入熊猫,在我看来,要进行这种简单转换,需要导入很多代码。我注意到,如果原始单位微秒单位,则datetime64.astype(datetime.datetime)它将返回一个datetime.datetime对象,而其他单位则返回整数时间戳。我使用Netcdf文件中的数据I / O 模块,该模块使用纳秒级单位进行转换,除非您首先转换为微秒级单位,否则转换将失败。这是示例转换代码,datetime64xarraydatetime64

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
Run Code Online (Sandbox Code Playgroud)

它仅在我的机器上进行过测试,该机器是最近发布的2017年Anaconda发行版的Python 3.6。我只是看了标量转换,没有检查基于数组的转换,尽管我猜这会很好。我也没有查看numpy datetime64源代码,以查看该操作是否有意义。