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

2024-10-02 16:29:25 发布

您现在位置:Python中文网/ 问答频道 /正文

我在numpy array中看到了一个非常奇怪的行为,当我在一个简单的操作中混合了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)}

有人知道为什么会这样吗?在


Tags: inimportnumpy元素asnpzeros数组
2条回答

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标量

^{pr2}$

正如@WallyBeaver指出的,ct[4,0] += dleng[4]*4就像ct[4,0] = ct[4,0] + dleng[4]*4。最后一个表达式是一个标量加上一个数组。在这种情况下,数据类型是由数组决定的,因此它最终是np.int8。在numpy docs中有一条关于此的注释:

Mixed scalar-array operations use a different set of casting rules that ensure that a scalar cannot “upcast” an array unless the scalar is of a fundamentally different kind of data (i.e., under a different hierarchy in the data-type hierarchy) than the array. This rule enables you to use scalar constants in your code (which, as Python types, are interpreted accordingly in ufuncs) without worrying about whether the precision of the scalar constant will cause upcasting on your large (small precision) array.

修复方法是将就地加法写成

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

因为你在做的是:

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

实际上是这样:

^{pr2}$

产生此功能的:

^{pr3}$

然后执行以下操作:

^{pr4}$

但实际上是在下面进行这种类型转换:

>>> a.astype(np.int32)
array([-127], dtype=int32)

相关问题 更多 >