我正在查看具有以下 if
测试的第三方库:
if isinstance(xx_, numpy.ndarray) and xx_.dtype is numpy.float64 and xx_.flags.contiguous:
xx_[:] = ctypes.cast(xx_.ctypes._as_parameter_,ctypes.POINTER(ctypes.c_double))
似乎 xx_.dtype is numpy.float64
总是失败:
>>> xx_ = numpy.zeros(8, dtype=numpy.float64)
>>> xx_.dtype is numpy.float64
False
测试 numpy 数组的 dtype
是 float64
的正确方法是什么?
原文由 Zero 发布,翻译遵循 CC BY-SA 4.0 许可协议
这是库中的错误。
dtype
可以动态构造对象。 NumPy 一直都是这样做的。无法保证他们在任何地方都被拘留,因此构建一个已经存在的dtype
会给你同样的结果。最重要的是,
np.float64
实际上不是dtype
;这是一个……我不知道这些类型叫什么,但是用于从数组字节构造标量对象的类型,通常在type
属性中找到dtype
,所以我将其称为dtype.type
。 (注意np.float64
是 NumPy 的数字塔类型和 Python 的数字塔 ABC 的子类,而np.dtype
当然不是。)通常,您可以互换使用它们;当您使用
dtype.type
— 或者,就此而言,本地 Python 数字类型 — 其中dtype
是预期的,dtype
同样,不能保证会被拘留),但这当然并不意味着它们是相同的:如果您使用内置类型,则
dtype.type
通常 是相同的:但是两个
dtype
通常不是:但同样,这些都不能保证。 (另外,请注意
np.float64
和float
使用完全相同的存储,但是是不同的类型。当然你也可以制作一个dtype('f8')
,保证to work the same asdtype(np.float64)
, but that doesn’t mean'f8'
is
, or even==
,np.float64
.)因此,有可能通过显式传递
np.float64
作为它的dtype
参数来构造一个数组,这意味着当你检查dtype.type
属性时,你会得到相同的实例不能保证。如果你传递np.dtype('float64')
,或者你要求 NumPy 从数据中推断它,或者你传递一个 dtype 字符串让它像'f8'
一样解析,等等,它更不可能匹配。更重要的是,您 绝对 不会将np.float64
返回为dtype
本身。那么,应该如何修复呢?
好吧,文档定义了两个
dtype
相等 的含义,这是一个有用的东西,我认为这可能是您在这里寻找的有用的东西。因此,只需将is
替换为 ---==
:但是,在某种程度上,我只是猜测这就是您要找的东西。 (它正在检查连续标志的事实意味着它可能会直接进入内部存储……但为什么它不检查 C 与 Fortran 顺序、字节顺序或其他任何内容?)