如何转换numpy。对象的Datetime64。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')
注意:从Timestamp中很容易得到datetime:
In [10]: ts.to_datetime()
Out[10]: datetime.datetime(2012, 5, 1, 0, 0)
但是我们如何从numpy中提取datetime或Timestamp。datetime64 (dt64) ?
.
更新:在我的数据集中有一个有点讨厌的例子(也许是激励的例子)似乎是:
dt64 = numpy.datetime64('2002-06-28T01:00:00.000000000+0100')
它应该是datetime。datetime(2002,6,28,1,0),而不是long (!) (1025222400000000000L)…
如果你想将整个pandas日期时间序列转换为常规的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)
....
它还支持时区:
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>)
....
注意:如果你操作的是Pandas系列,你不能在整个系列上调用to_pydatetime()。你需要在每个单独的datetime64上调用.to_pydatetime(),使用一个列表理解或类似的东西:
datetimes = [val.to_pydatetime() for val in df.problem_datetime_column]
一个选项是使用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)
实际上,所有这些datetime类型都很困难,而且可能存在问题(必须仔细跟踪时区信息)。以下是我所做的,尽管我承认我担心至少有一部分是“非设计”的。此外,这可以根据需要做得更紧凑一些。
从numpy开始。datetime64 dt_a:
dt_a
numpy.datetime64 (2015 - 04 - 24 - t23:11:26.270000 - 0700)
dt_a1 = dt_a.tolist() #生成UTC格式的datetime对象,但不包含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'))
... 当然,也可以根据需要压缩成一行。
欢迎来到地狱。
你可以将datetime64对象传递给pandas。时间戳:
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')
同时,熊猫。To_datetime可以使用(这是开发版本之外的,还没有检查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))
如果你想将整个pandas日期时间序列转换为常规的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)
....
它还支持时区:
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>)
....
注意:如果你操作的是Pandas系列,你不能在整个系列上调用to_pydatetime()。你需要在每个单独的datetime64上调用.to_pydatetime(),使用一个列表理解或类似的东西:
datetimes = [val.to_pydatetime() for val in df.problem_datetime_column]