[Python] 在日期时间,时间戳和日期时间64之间进行转换


Answers

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

Question

如何将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')

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

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 dt_a开始:

dt_a

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

dt_a1 = dt_a.tolist()#以UTC形式生成日期时间对象,但不包含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'))

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




有些解决方案适用于我,但numpy会弃用一些参数。 对我更好的解决方案是将日期读取为熊猫日期时间,并明确指出熊猫物件的年,月和日。 以下代码适用于最常见的情况。

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)



一种选择是使用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因为它变成了"offset-aware"

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)



>>> dt64.tolist()
datetime.datetime(2012, 5, 1, 0, 0)

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




这篇文章已经有4年了,我仍然在为这个转换问题而努力 - 所以这个问题在某种意义上在2017年仍然有效。 我有些震惊的是,numpy文档不容易提供简单的转换算法,但这是另一回事。

我遇到了另一种方法来进行只涉及模块numpydatetime的转换,它不需要导入大熊猫,这在我看来是很多代码来导入这样一个简单的转换。 我发现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

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