如何转换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]

其他回答

这篇文章已经写了4年了,我仍然在这个转换问题上挣扎——所以在某种意义上,这个问题在2017年仍然很活跃。numpy文档没有提供简单的转换算法,这让我有些震惊,但那是另一回事了。

I have come across another way to do the conversion that only involves modules numpy and datetime, it does not require pandas to be imported which seems to me to be a lot of code to import for such a simple conversion. I noticed that datetime64.astype(datetime.datetime) will return a datetime.datetime object if the original datetime64 is in micro-second units while other units return an integer timestamp. I use module xarray for data I/O from Netcdf files which uses the datetime64 in nanosecond units making the conversion fail unless you first convert to micro-second units. Here is the example conversion code,

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

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

唯一的方法,我设法转换列“日期”在熊猫dataframe包含时间信息numpy数组如下:(dataframe是从csv文件“csv .csv”读取)

import pandas as pd
import numpy as np

df = pd.read_csv("csvIn.csv")
df["date"] = pd.to_datetime(df["date"])
timestamps = np.array([np.datetime64(value) for dummy, value in df["date"].items()])

一个选项是使用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)

一些解决方案很适合我,但numpy将弃用一些参数。 对我来说,更好的解决方案是将日期读取为pandas datetime,并明确地提取pandas对象的年、月和日。 下面的代码适用于最常见的情况。

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)

我已经无数次地回到这个答案,所以我决定拼凑一个快速的小类,它将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)

我要把它放在我的工具箱里,直觉告诉我我还会用到它。