Python 在日期时间、时间戳和日期时间 64 之间转换

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/13703720/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-18 09:24:44  来源:igfitidea点击:

Converting between datetime, Timestamp and datetime64

pythondatetimenumpypandas

提问by Andy Hayden

How do I convert a numpy.datetime64object to a datetime.datetime(or Timestamp)?

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

In the following code, I create a datetime, timestamp and datetime64 objects.

在下面的代码中,我创建了一个日期时间、时间戳和 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')

Note: it's easy to get the datetime from the Timestamp:

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

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

But how do we extract the datetimeor Timestampfrom a numpy.datetime64(dt64)?

但是我们如何从 a ( ) 中提取datetimeor呢?Timestampnumpy.datetime64dt64

.

.

Update: a somewhat nasty example in my dataset (perhaps the motivating example) seems to be:

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

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

which should be datetime.datetime(2002, 6, 28, 1, 0), and not a long (!) (1025222400000000000L)...

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

采纳答案by jfs

To convert numpy.datetime64to datetime object that represents time in UTC on numpy-1.8:

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

The above example assumes that a naive datetime object is interpreted by np.datetime64as time in UTC.

上面的例子假设一个简单的 datetime 对象被解释np.datetime64为 UTC 时间。



To convert datetime to np.datetime64 and back (numpy-1.6):

将日期时间转换为 np.datetime64 并返回 ( numpy-1.6):

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

It works both on a single np.datetime64 object and a numpy array of np.datetime64.

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

Think of np.datetime64 the same way you would about np.int8, np.int16, etc and apply the same methods to convert beetween Python objects such as int, datetime and corresponding numpy objects.

以与 np.int8、np.int16 等相同的方式考虑 np.datetime64,并应用相同的方法在 Python 对象(如 int、datetime 和相应的 numpy 对象)之间进行转换。

Your "nasty example" works correctly:

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

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

I can reproduce the longvalue on numpy-1.8.0installed as:

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

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

The same example:

同样的例子:

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

It returns longbecause for numpy.datetime64type .astype(datetime)is equivalent to .astype(object)that returns Python integer (long) on numpy-1.8.

它返回long是因为 fornumpy.datetime64类型.astype(datetime)等同于.astype(object)返回 Python integer( long) on numpy-1.8

To get datetime object you could:

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

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

To get datetime64 that uses seconds directly:

要获取直接使用秒的 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)

The numpy docssay that the datetime API is experimental and may change in future numpy versions.

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

回答by Andy Hayden

One option is to use str, and then to_datetime(or similar):

一种选择是使用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))

Note: it is not equal to dtbecause it's become "offset-aware":

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

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

This seems inelegant.

这看起来很不雅观。

.

.

Update: this can deal with the "nasty example":

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

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)

回答by eumiro

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

For DatetimeIndex, the tolistreturns a list of datetimeobjects. For a single datetime64object it returns a single datetimeobject.

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

回答by Wes McKinney

Welcome to hell.

欢迎来到地狱。

You can just pass a datetime64 object to pandas.Timestamp:

您可以将 datetime64 对象传递给pandas.Timestamp

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

I noticed that this doesn't work right though in NumPy 1.6.1:

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

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

Also, pandas.to_datetimecan be used (this is off of the dev version, haven't checked v0.9.1):

此外,pandas.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))

回答by Quant

You can just use the pd.Timestamp constructor. The following diagram may be useful for this and related questions.

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

Conversions between time representations

时间表示之间的转换

回答by fantabolous

If you want to convert an entire pandas series of datetimes to regular python datetimes, you can also use .to_pydatetime().

如果要将整个 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)
   ....

It also supports timezones:

它还支持时区:

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

NOTE: If you are operating on a Pandas Series you cannot call to_pydatetime()on the entire series. You will need to call .to_pydatetime()on each individual datetime64 using a list comprehension or something similar:

注意:如果您在 Pandas 系列上操作,则无法调用to_pydatetime()整个系列。您将需要.to_pydatetime()使用列表理解或类似方法调用每个单独的 datetime64:

datetimes = [val.to_pydatetime() for val in df.problem_datetime_column]

回答by yoder

indeed, all of these datetime types can be difficult, and potentially problematic (must keep careful track of timezone information). here's what i have done, though i admit that i am concerned that at least part of it is "not by design". also, this can be made a bit more compact as needed. starting with a numpy.datetime64 dt_a:

实际上,所有这些日期时间类型都可能很困难,并且可能存在问题(必须仔细跟踪时区信息)。这就是我所做的,虽然我承认我担心至少有一部分是“不是设计的”。此外,这可以根据需要做得更紧凑一些。从 numpy.datetime64 dt_a 开始:

dt_a

dt_a

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

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

dt_a1 = dt_a.tolist() # yields a datetime object in UTC, but without tzinfo

dt_a1

dt_a1 = dt_a.tolist() # 产生一个 UTC 日期时间对象,但没有 tzinfo

dt_a1

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

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

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

... and of course, that can be compressed into one line as needed.

...当然,可以根据需要将其压缩为一行。

回答by Crystal

import numpy as np
import pandas as pd 

def np64toDate(np64):
    return pd.to_datetime(str(np64)).replace(tzinfo=None).to_datetime()

use this function to get pythons native datetime object

使用这个函数来获取python的原生日期时间对象

回答by ndl303

This post has been up for 4 years and I still struggled with this conversion problem - so the issue is still active in 2017 in some sense. I was somewhat shocked that the numpy documentation does not readily offer a simple conversion algorithm but that's another story.

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

I have come across another way to do the conversion that only involves modules numpyand 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.datetimeobject if the original datetime64is in micro-second unitswhile other units return an integer timestamp. I use module xarrayfor data I/O from Netcdf files which uses the datetime64in nanosecond units making the conversion fail unless you first convert to micro-second units. Here is the example conversion code,

我遇到了另一种只涉及模块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

Its only tested on my machine, which is Python 3.6 with a recent 2017 Anaconda distribution. I have only looked at scalar conversion and have not checked array based conversions although I'm guessing it will be good. Nor have I looked at the numpy datetime64 source code to see if the operation makes sense or not.

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

回答by MikeyE

I've come back to this answer more times than I can count, so I decided to throw together a quick little class, which converts a Numpy datetime64value to Python datetimevalue. I hope it helps others out there.

我已经无数次回到这个答案了,所以我决定把一个快速的小类放在一起,它将一个 Numpydatetime64值转换为 Pythondatetime值。我希望它可以帮助其他人。

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)

I'm gonna keep this in my tool bag, something tells me I'll need it again.

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