Python numpy数组:混合int32和int8时的结果错误

Python numpy数组:混合int32和int8时的结果错误,python,arrays,numpy,Python,Arrays,Numpy,我在numpy数组中看到了一个非常奇怪的行为,当我在一个简单的操作中混合了int32和int8数组时,在获取+=dleng[4]*4的结果时,int32数组元素ct[4,0]似乎变成了8bit: 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]: dle

我在numpy数组中看到了一个非常奇怪的行为,当我在一个简单的操作中混合了int32和int8数组时,在获取
+=dleng[4]*4
的结果时,int32数组元素
ct[4,0]
似乎变成了8bit:

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)}

有人知道为什么会发生这种情况吗?

这是因为你正在做的是:

>>> 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)

dleng[4]*4
是一个数组:

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
。关于这一点,请参见:

混合标量数组操作使用不同的强制转换规则集 确保标量不能“向上投射”数组,除非标量 属于根本不同类型的数据(即,在不同的 数据类型层次结构中的层次结构)而不是数组。这条规则 使您能够在代码中使用标量常量(例如Python) 类型,在ufuncs中进行相应的解释,而无需担心 标量常量的精度是否会导致上转换 您的大(小精度)阵列

修复方法是将就地添加写入

ct[4,0] += dleng[4,0]*4

我不明白为什么
ct[4,0]+dleng[4]*4
产生
array([-127],dtype=int8)
——为什么它被转换为int8而不是int32?啊,在看到你和沃伦的答案后,我现在明白了。是的,
ct[4,0]
117
,然后在添加后被转换为
int8
。好的,这很有意义。以后一定要注意!
ct[4,0] += dleng[4,0]*4