我正在查看具有以下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
的正确方法是什么?
答案 0 :(得分:20)
这是lib中的一个错误。
dtype
objects可以动态构建。 NumPy一直这样做。无法保证他们被实习的任何地方,因此构建已经存在的dtype
会给你相同的。{/ p>
最重要的是,np.float64
实际上不是dtype
;它是...我不知道这些类型被调用了什么,但是用于从数组字节构造标量对象的类型,通常在type
的{{1}}属性中找到,所以我'我打算称它为dtype
。 (注意dtype.type
是NumPy的数字塔类型和Python的数字塔ABC的子类,而np.float64
当然不是。)
通常情况下,您可以互换使用;当您使用np.dtype
时 - 或者就此而言,使用本机Python数字类型 - 其中dtype.type
是预期的,动态构建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')
相同{1}},但这并不意味着dtype(np.float64)
'f8'
,甚至is
,==
。)
因此,通过显式传递np.float64
作为其np.float64
参数来构造数组可能意味着当您检查dtype
属性时,您将返回相同的实例,但这不是'保证。如果您传递dtype.type
,或者您要求NumPy从数据中推断出它,或者您传递一个dtype字符串以便像np.dtype('float64')
等那样进行解析,那么它就更不可能匹配。更重要的是,肯定不会'f8'
返回np.float64
本身。
那么,应该如何解决?
嗯,文档定义了两个dtype
对于相等意味着什么,这是一个有用的东西,我认为这可能是你在这里寻找的有用的东西。因此,只需将dtype
替换为is
:
==
然而,在某种程度上,我只是猜测你正在寻找的东西。 (事实上它正在检查连续的标志意味着它可能会直接进入内部存储......但是为什么不检查C与Fortran顺序,或字节顺序,还是其他任何东西?)
答案 1 :(得分:1)
尝试:
x = np.zeros(8, dtype=np.float64)
print x.dtype is np.dtype(np.float64))
is
测试2个对象的身份,是否具有相同的id()
。它用于测试is None
,但在测试整数或字符串时可能会出错。但在这种情况下,还有一个问题,x.dtype
和np.float64
不是同一个类。
isinstance(x.dtype, np.dtype) # True
isinstance(np.float64, np.dtype) # False
x.dtype.__class__ # numpy.dtype
np.float64.__class__ # type
np.float64
实际上是一个函数。 np.float64()
生成0.0
。 x.dtype()
会产生错误。 (更正np.float64
是一个类。)
在我的互动测试中:
x.dtype is np.dtype(np.float64)
返回True
。但我不知道这种情况是普遍的,还是仅仅是某种本地缓存的结果。 dtype
文档提到了dtype
属性:
dtype.num 21种不同内置类型中每种类型的唯一编号。
两个dtypes都为此12
提供num
。
x.dtype == np.float64
测试True
。
此外,使用type
有效:
x.dtype.type is np.float64 # True
当我导入ctypes
并执行cast
(使用您的xx_
)时,我收到错误消息:
ValueError:使用序列设置数组元素。
我不太了解ctypes
以了解它正在尝试做什么。看起来它正在对data
的{{1}}指针进行类型转换,xx_
与xx_.ctypes._as_parameter_
的数字相同。
在xx_.__array_interface__['data'][0]
测试代码中,我找到了这些dtype测试:
numpy
issubclass(arr.dtype.type, (nt.integer, nt.bool_)
assert_(dat.dtype.type is np.float64)
assert_equal(A.dtype.type, np.unicode_)
assert_equal(r['col1'].dtype.kind, 'i')
文档也谈到了
numpy
两者都使用np.issubdtype(x.dtype, np.float64)
np.issubsctype(x, np.float64)
。
进一步跟踪issubclass
代码表明c
被评估为:
x.dtype == np.float64
也就是说,标量类型转换为x.dtype.num == np.dtype(np.float64).num
,并比较dtype
属性。代码位于.num
的{{1}},scalarapi.c
,descriptor.c