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
,但我没有它去挖掘它。
给定以下代码:
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
,但我没有它去挖掘它。