将int添加到uint8时的奇怪类型转换



我对python/numpy在类型转换无符号整数时的工作方式有些困惑。

的例子:

import numpy as np
x = np.array([255], dtype=np.uint8)
y = x + 1

结果如下:

In[0]: y
Out[0]: array([0], dtype=uint8)

我知道uint8不能存储大于255的整数,所以它循环回零。

现在我试试:

z = x + 256
给了

:

In[1]: z
Out[1]: array([511], dtype=uint16)

因此,在这种情况下,该类型已更改为具有更多字节的类型,以容纳较大的数字,但仅当要添加的整数本身不适合较小的类型时。(有趣的是,x + 255没有给出uint16的结果)

这让我觉得有点奇怪的行为。这背后有什么逻辑吗?我本以为更一致的做法是在第一个例子中也将类型更改为uint16。

这种行为似乎源于一种可以理解的愿望,即将数组强制转换保持在绝对最低限度。

考虑
z = np.uint8(255)
z + 1
# 256
type(z+1)
# numpy.int64

,其中文字1的类型为int。在这种情况下,两个操作数似乎都被强制转换为np.int64。但这与结果无关!

zz = np.uint8(1)
type(zz + 1)
# numpy.int64
如果使用数组而不是简单的整数,则

类型转换会有所不同。

x = np.array([255], dtype=np.uint8)
x + 1
# array([0], dtype=uint8)

在我看来,这可能是这种情况,因为将整个数组从一种类型转换为另一种类型将是一个巨大的计算工作量,所以只有在查看所有数组元素之前100%确定这将是必要的时才会这样做,即只有当另一个操作数本身不适合当前类型时。事实上,即使我们取

b = np.int16(1)
x+b
# array([0], dtype=uint8)

,因此它实际上将右操作数强制转换为更小的类型,所有这些都是为了保存数组的类型。另一方面,当添加两个np。数组时,总是将类型转换为较大的类型。

长话短说:-简单的整数加法总是将操作数转换为较大的类型-添加numpy数组和一个整数,如果这足以表示整数,则转换为数组的类型,否则转换为整数的类型-添加两个numpy数组,将其转换为操作数的较大类型(如两个整数)

最新更新