Numpy returns 在 windows 和 unix 上的不同结果

Numpy returns different results on windows and unix

给定以下代码:

import numpy as np
c = [
    [1, 2, 3],
    [4, 5, 6],
    [7, 8, 9]
]

c = np.array(c)
print((c * c.transpose()).prod())

在我的 windows 机器上它 returns "-1462091776"(不确定它是如何从所有这些正面中得到负面的)。 在 ubuntu 它 returns "131681894400"

有人知道这是怎么回事吗?

编辑:显然这是一个溢出问题。 (感谢@rafaelc!) 但它是可重现的(也感谢@richardec 的测试)

所以现在问题变成了..这是我应该报告的错误吗?我应该向谁报告?

我有足够多的评论,我认为“答案”是战争运行ted。

发生了什么事?

Not sure how it got a negative from all those positives

正如@rafaelc 指出的那样,您 运行 陷入了整数溢出。您可以在提供的 wikipedia link 中阅读更多详细信息。

溢出的原因是什么?

根据 this thread,numpy 使用操作系统的 C long 类型作为整数的默认值 dtype。所以当你写这行代码时:

c = np.array(c)

dtype默认是numpy的默认整型数据类型,也就是操作系统的Clong。 Windows 的 Microsoft C 实现中 long 的大小为 4 个字节(x8 bits/byte = 32 位),因此您的 dtype 默认为 32 位整数。

为什么这个计算会溢出?

In [1]: import numpy as np

In [2]: np.iinfo(np.int32)
Out[2]: iinfo(min=-2147483648, max=2147483647, dtype=int32)

32 位有符号整数数据类型可以表示的最大数是 2147483647。如果您只从一个轴看您的产品:

In [5]: c * c.T
Out[5]:
array([[ 1,  8, 21],
       [ 8, 25, 48],
       [21, 48, 81]])

In [6]: (c * c.T).prod(axis=0)
Out[6]: array([  168,  9600, 81648])

In [7]: 168 * 9600 * 81648
Out[7]: 131681894400

您可以看到 131681894400 >> 2147483647(在数学中,符号 >> 表示“大得多”)。由于 131681894400 远大于 32 位 long 可以表示的最大整数,因此发生溢出。

不过在Linux

还好

在Linux中,一个long是8字节(x8bits/byte = 64位)。为什么? an SO thread 在评论中对此进行了讨论。

“这是一个错误吗?”

不,虽然这很烦人,我承认。

尽管如此,明确说明您的数据类型通常是个好主意,所以下次:

c = np.array(c, dtype='int64')

# or
c = np.array(c, dtype=np.int64)

我应该向谁报告错误?

同样,这不是一个错误,但如果是,你会在 numpy github 上打开一个问题(你也可以在这里仔细阅读源代码代码)。某处有证据证明 numpy 如何使用操作系统的默认 C long,但我没有它去挖掘它。