numpy 数组转换规则不 'safe'

numpy array casting ruled not 'safe'

将一个 numpy 数组与另一个数组建立索引 - 两者都定义为 dtype='uint32'。使用 numpy.take 索引并得到不安全的转换错误。以前没有遇到过这个。知道发生了什么事吗?

Python 2.7.8 |Anaconda 2.1.0 (32-bit)| (default, Jul  2 2014, 15:13:35) [MSC v.1500 32 bit (Intel)] on win32
Type "copyright", "credits" or "license()" for more information.

>>> import numpy
>>> numpy.__version__
'1.9.0'

>>> a = numpy.array([9, 7, 5, 4, 3, 1], dtype=numpy.uint32)
>>> b = numpy.array([1, 3], dtype=numpy.uint32)
>>> c = a.take(b)

Traceback (most recent call last):
  File "<pyshell#12>", line 1, in <module>
    c = a.take(b)
TypeError: Cannot cast array data from dtype('uint32') to dtype('int32') according to the rule 'safe'

这在处理需要指定索引或长度的 NumPy 函数时很常见(不只是 take,参见示例 here)。

问题是,出于索引目的,NumPy 想将您的 uint32 数组视为 int32 数组(这可能是您的 32 位上的 "pointer" 整数类型系统,np.intp) 并希望将其转换为该类型。

它不能安全地执行此操作 - 无符号数组中的某些整数可能无法表示为带符号的 32 位整数。您看到的错误反映了这一点。

这意味着如果 b 具有数据类型 int64 或浮点数据类型,您将得到相同的错误,但如果它是 int32 或更小的整数数据类型则不会。

就其价值而言,这不是索引符号 a[b] 的直接问题,它允许不安全的转换(但如果索引超出范围则会引发错误)。例如尝试 a[2**31] - NumPy 转换为 int32 但随后抱怨索引 -2147483648 超出范围。