数据类型‘ datetime64[ ns ]’和‘ < M8[ ns ]’之间的差异?

我在熊猫身上创建了一个 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 for Data Analysis 》一书中的例子。

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

In [353]: ts.index.dtype


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

When I do exactly the same operation in the console I get:

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

两种类型的 'datetime64[ns]''<M8[ns]'有什么区别?

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

139524 次浏览

datetime64[ns]是通用的 dtype,而 <M8[ns]是特定的 dtype。一般的 dtype 映射到特定的 dtype,但是在 NumPy 的安装之间可能有所不同。

在字节顺序为小端点的机器上,两者之间没有区别 np.dtype('datetime64[ns]')np.dtype('<M8[ns]'):

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

然而,在大端机上,np.dtype('datetime64[ns]')等于 np.dtype('>M8[ns]')

因此,datetime64[ns]映射到 <M8[ns]>M8[ns],这取决于机器的端点。

There are many other similar examples of general dtypes mapping to specific dtypes: int64映射到 <i8>i8,而 int映射到 int32int64 取决于操作系统的位架构以及 NumPy 是如何编译的。


Apparently, the repr of the datetime64 dtype has change since the time the book was written to show the endian-ness of the dtype.

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

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