我正在查看具有以下 if
-test 的第三方库:
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
的正确方法是什么?
最佳答案
这是库中的错误。
dtype
objects可以动态构造。 NumPy 一直都是这样做的。无法保证他们在任何地方都被拘留,因此构建一个 dtype
已经存在的会给你相同的。
最重要的是,np.float64
实际上不是 dtype
;这是一个……我不知道这些类型叫什么,但是用于从数组字节构造标量对象的类型,通常在 type
中找到dtype
的属性,所以我将其称为 dtype.type
. (注意 np.float64
是 NumPy 的数字塔类型和 Python 的数字塔 ABC 的子类,而 np.dtype
当然不是。)
通常,您可以互换使用它们;当你使用 dtype.type
— 或者,就此而言,本地 Python 数字类型 — 其中 dtype
预期,一个dtype
是即时构建的(同样,不能保证被实习),但这当然并不意味着它们是相同的:
>>> np.float64 == np.dtype(np.float64) == np.dtype('float64')
True
>>> np.float64 == np.dtype(np.float64).type
True
dtype.type
如果您使用内置类型,通常将是相同的:
>>> np.float64 is np.dtype(np.float64).type
True
但是两个dtype
通常不是:
>>> np.dtype(np.float64) is np.dtype('float64')
False
但同样,这一切都无法保证。 (另外,请注意 np.float64
和 float
使用完全相同的存储,但是是不同的类型。当然你也可以制作一个 dtype('f8')
,它保证与 dtype(np.float64)
的工作方式相同,但这并不不是指 'f8'
is
,甚至是 ==
, np.float64
。)
因此,可以通过显式传递 np.float64
来构造数组作为其 dtype
参数将意味着您在检查 dtype.type
时返回相同的实例属性,但这不能保证。如果你通过 np.dtype('float64')
,或者你要求 NumPy 从数据中推断它,或者你传递一个 dtype 字符串让它像 'f8'
一样解析。等,匹配的可能性就更小了。更重要的是,你绝对不会得到np.float64
返回为 dtype
本身。
那么,应该如何修复呢?
好吧,文档定义了两个 dtype
的含义s 是相等,这是一个有用的东西,我认为这可能是您在这里寻找的有用的东西。所以,只需替换 is
与 ==
:
if isinstance(xx_, numpy.ndarray) and xx_.dtype == numpy.float64 and xx_.flags.contiguous:
但是,在某种程度上,我只是猜测这就是您要查找的内容。 (它正在检查连续标志的事实意味着它可能会直接进入内部存储……但是为什么它不检查 C 与 Fortran 顺序、字节顺序或其他任何内容?)
关于python - 测试 numpy.dtype 的正确方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26921836/