我在numpy数组中看到了一个非常奇怪的行为,当我在一个简单的操作中混合int32和int8数组时,int32数组元素ct[4,0]
在获取+= dleng[4]*4
的结果时似乎变为8位:
import numpy as np
In[3]: ct = np.zeros((6,1), np.int32)
In[4]: ct
Out[4]:
array([[0],
[0],
[0],
[0],
[0],
[0]], dtype=int32)
In[5]: dleng = np.zeros((6, 1), np.int8)
In[6]: dleng[0] = 2
dleng[1] = 3
dleng[2] = 4
dleng[3] = 7
dleng[4] = 3
dleng[5] = 5
In[7]: dleng
Out[7]:
array([[2],
[3],
[4],
[7],
[3],
[5]], dtype=int8)
In[8]: ct[4] = 117
In[9]: ct
Out[9]:
array([[ 0],
[ 0],
[ 0],
[ 0],
[117],
[ 0]], dtype=int32)
In[10]: ct[4,0] += dleng[4]*4
In[11]: ct
Out[11]:
array([[ 0],
[ 0],
[ 0],
[ 0],
[-127],
[ 0]], dtype=int32)}
有谁知道为什么会这样?
答案 0 :(得分:1)
这是因为你在做的是:
>>> ct[4,0] += dleng[4]*4
实际上是这样的:
>>> ct[4,0] = ct[4,0] + dleng[4]*4
产生这个:
>>> ct[4,0] + dleng[4]*4
array([-127], dtype=int8)
然后这样做:
>>> ct[4,0] = array([-127], dtype=int8)
但是真的在封面下进行这种类型转换:
>>> a.astype(np.int32)
array([-127], dtype=int32)
答案 1 :(得分:1)
dleng[4]*4
是一个数组:
In [94]: dleng[4]
Out[94]: array([3], dtype=int8)
In [95]: dleng[4]*4
Out[95]: array([12], dtype=int8)
虽然ct[4, 0]
是标量且类型为np.int32
:
In [98]: ct[4,0]
Out[98]: 117
In [99]: type(_)
Out[99]: numpy.int32
正如@WallyBeaver所指出的那样,ct[4,0] += dleng[4]*4
就像ct[4,0] = ct[4,0] + dleng[4]*4
。最后一个表达式是标量加上数组。在这种情况下,数据类型由数组决定,因此最终为np.int8
。 numpy docs中有一个关于此的说明:
混合标量数组操作使用一组不同的强制转换规则 除非标量,否则确保标量不能“向上”数组 是一种根本不同的数据(即不同的数据) 数据类型层次结构中的层次结构)而不是数组。这个规则 使您能够在代码中使用标量常量(作为Python 类型,在ufuncs中相应地解释)而不用担心 标量常量的精度是否会导致上升 你的大(小精度)阵列。
修复是将就地添加写为
ct[4,0] += dleng[4,0]*4