我有一个(1000,1000,3)整形的 numpy 数组 ( dtype='float32'),当我将其转换为时,dtype='uint8'我在 Windows 和 Mac 上得到不同的结果。
数组可在此处获取:https://www.dropbox.com/s/jrs4n2ayh86s0fn/image.npy ?dl=0
在苹果电脑上
>>> import numpy as np
>>> X = np.load('image.npy')
>>> X = X.astype('uint8')
>>> X.sum()
167942490
Run Code Online (Sandbox Code Playgroud)
在 Windows 上
>>> import numpy as np
>>> X = np.load('image.npy')
>>> X = X.astype('uint8')
>>> X.sum()
323510676
Run Code Online (Sandbox Code Playgroud)
也用这个数组重现:
import numpy as np
X = np.array([
[[46410., 42585., 32640.],
[45645., 41820., 31875.],
[45390., 41310., 32130.]],
[[44880., 41055., 31110.],
[44115., 40290., 30345.],
[46410., 42330., 33150.]],
[[45390., 41310., 32130.],
[46155., 42075., 32895.],
[42840., 38760., 30090.]]], dtype=np.float32)
print(X.sum(), X.astype('uint8').sum())
Run Code Online (Sandbox Code Playgroud)
1065135.0 2735在 Windows 和1065135.0 1860Mac 上打印。
以下是不同操作系统、Python 和 Numpy 的结果:
Python 3.8.8 (Win) Numpy 1.22.4 => 1065135.0 2735
Python 3.10.6 (Mac) Numpy 1.24.2 => 1065135.0 2735
Python 3.7.12 (Mac) Numpy 1.21.6 => 1065135.0 1860
Run Code Online (Sandbox Code Playgroud)
此问题是由于错误的转换导致整数溢出。事实上,Numpy 使用 C 类型转换来转换值,但是将 0-255 范围之外的浮点数转换为 8 位无符号整数会导致C 中出现未定义的行为。在这种情况下,我们尝试在不影响性能的情况下报告错误,但是这并非在所有情况下都可行。最新版本的 Numpy 应该可以解决这个问题,但问题仍然部分未解决。请参阅1.24.0 发行说明、此问题和此问题,以及此 PR(据我所知,对此问题的第一个引用可以在此处找到)。
无论如何,虽然您的目标计算机上可能无法检测到错误,但将浮点数转换为 0-255 范围之外的数字是不安全的,您不应期望得到正确的结果。您需要调整您的代码,以便首先不会出现溢出。我还建议您至少使用 Numpy 1.24.0 版本,以便更好地跟踪此类错误。
相关文章:为什么 numpy 处理溢出不一致?
| 归档时间: |
|
| 查看次数: |
185 次 |
| 最近记录: |