数据类型“datetime64[ns]”和“<M8[ns]”之间的区别?

Posted

技术标签:

【中文标题】数据类型“datetime64[ns]”和“<M8[ns]”之间的区别?【英文标题】:Difference between data type 'datetime64[ns]' and '<M8[ns]'? 【发布时间】:2015-05-26 05:28:49 【问题描述】:

我在 pandas 中创建了一个 TimeSeries:

In [346]: from datetime import datetime

In [347]: dates = [datetime(2011, 1, 2), datetime(2011, 1, 5), datetime(2011, 1, 7),

 .....: datetime(2011, 1, 8), datetime(2011, 1, 10), datetime(2011, 1, 12)]

In [348]: ts = Series(np.random.randn(6), index=dates)

In [349]: ts

Out[349]: 

2011-01-02 0.690002

2011-01-05 1.001543

2011-01-07 -0.503087

2011-01-08 -0.622274

2011-01-10 -0.921169

2011-01-12 -0.726213

我正在关注“用于数据分析的 Python”一书中的示例。

在以下段落中,作者检查了索引类型:

In [353]: ts.index.dtype

Out[353]: dtype('datetime64[ns]')

当我在控制台中执行完全相同的操作时,我得到:

ts.index.dtype
dtype('<M8[ns]')

'datetime64[ns]''&lt;M8[ns]'这两种类型有什么区别?

为什么我会得到不同的类型?

【问题讨论】:

我无法回答这个问题,但请记住,这本书大约有 3 年的历史(因此基于旧版本的 pandas),所以发现这样的一些差异是很常见的(尤其是对索引和日期时间的东西来说是正确的),尽管大多数示例仍然或多或少相同。 在DataCamp课程Machine Learning for Time Series Data的练习中遇到同样的问题,导致TypeError: ufunc subtract cannot use operands with types dtype('&lt;M8[ns]') and dtype('float64') 【参考方案1】:

一些背景知识将有助于理解输出的细微差别。

Numpy 具有精细的数据类型层次结构。类型信息作为属性存储在数据类型对象中,该对象是numpy.dtype 类的实例。它描述了应如何解释与数组项对应的固定大小内存块中的字节(字节顺序、字节数等)。

只需创建dtype 的实例即可检查各种属性。

In [1]: import numpy as np

In [2]: dt = np.datetime64('1980', 'ns')

In [3]: dt
Out[3]: numpy.datetime64('1980-01-01T00:00:00.000000000')

In [4]: dt.dtype
Out[4]: dtype('<M8[ns]')

In [5]: dt.dtype.char
Out[5]: 'M'

In [6]: dt.dtype.name
Out[6]: 'datetime64[ns]'

In [7]: dt.dtype.str
Out[7]: '<M8[ns]'

In [8]: dt.dtype.type
Out[8]: numpy.datetime64

reprstr 是对象的字符串表示形式,对于相同的底层数据类型,每个都可以有不同的输出。

In [9]: repr(dt.dtype)
Out[9]: "dtype('<M8[ns]')"

In [10]: str(dt.dtype)
Out[10]: 'datetime64[ns]'

应用程序(shell、控制台、调试器等)可以调用其中任何一个,因此相同类型的输出可能看起来不同。

尽管如此令人困惑,但在位宽、类型别名等方面仍然存在更多细微差别。有关血腥细节,请参阅 Data types in Python, Numpy and Pandas。

【讨论】:

【参考方案2】:

datetime64[ns] 是通用数据类型,而&lt;M8[ns] 是特定数据类型。一般 dtypes 映射到特定 dtypes,但可能与 NumPy 的一个安装不同。

在字节序为little endian的机器上,两者没有区别 np.dtype('datetime64[ns]')np.dtype('&lt;M8[ns]'):

In [6]: np.dtype('datetime64[ns]') == np.dtype('<M8[ns]')
Out[6]: True

但是,在大端机器上,np.dtype('datetime64[ns]') 将等于 np.dtype('&gt;M8[ns]')

所以datetime64[ns] 映射到&lt;M8[ns]&gt;M8[ns],具体取决于机器的字节序。

还有许多其他类似的通用 dtype 映射到特定 dtype 的示例: int64 映射到 &lt;i8&gt;i8int 映射到 int32int64 取决于操作系统的位架构以及 NumPy 的编译方式。


显然,datetime64 dtype 的 repr 自从这本书被写出来以显示 dtype 的字节顺序以来发生了变化。

【讨论】:

尽管我可以重现@unutbu 的比较测试,但我得到了TypeError,在提到的书写完后四年

以上是关于数据类型“datetime64[ns]”和“<M8[ns]”之间的区别?的主要内容,如果未能解决你的问题,请参考以下文章

将具有 dtypes datetime64[ns] 和 timedelta64[ns] 的数据帧导入到 google bigquery 表

将 datetime64[ns, UTC] pandas 列转换为 datetime

如何使用 datetime64[ns] 和 pandas 计算天数?

如何仅绘制熊猫 datetime64[ns] 属性的时间

Pandas 数据类型

pandas 中 datetime 和 datetime64[ns] 的比较