繁体   English   中英

numpy数组中的整数溢出

[英]Integer overflow in numpy arrays

import numpy as np
a = np.arange(1000000).reshape(1000,1000)
print(a**2)

有了这个代码,我得到了这个答案。 为什么我得到负值?

[[         0          1          4 ...,     994009     996004     998001]
 [   1000000    1002001    1004004 ...,    3988009    3992004    3996001]
 [   4000000    4004001    4008004 ...,    8982009    8988004    8994001]
 ..., 
 [1871554624 1873548625 1875542628 ..., -434400663 -432404668 -430408671]
 [-428412672 -426416671 -424420668 ..., 1562593337 1564591332 1566589329]
 [1568587328 1570585329 1572583332 ..., -733379959 -731379964 -729379967]]

在您的平台上, np.arange 返回一个 dtype 'int32' 数组:

In [1]: np.arange(1000000).dtype
Out[1]: dtype('int32')

数组的每个元素都是一个 32 位整数。 平方导致不适合 32 位的结果。 结果被裁剪为 32 位,但仍被解释为 32 位整数,这就是您看到负数的原因。

编辑:在这种情况下,您可以通过在平方之前构造一个 dtype 'int64' 数组来避免整数溢出:

a=np.arange(1000000,dtype='int64').reshape(1000,1000)

请注意,您发现的问题是使用 numpy 时固有的危险。 您必须谨慎选择 dtype,并事先知道您的代码不会导致算术溢出。 为了速度,numpy 不能也不会在发生这种情况时发出警告。

请参阅http://mail.scipy.org/pipermail/numpy-discussion/2009-April/041691.html在 numpy 邮件列表上对此进行讨论。

python integers 没有这个问题,因为它们在溢出时会自动升级为 python long integers。

因此,如果您确实设法使 int64 溢出,一种解决方案是在 numpy 数组中使用 python int:

import numpy
a=numpy.arange(1000,dtype=object)
a**20

numpy 整数类型是固定宽度的,您会看到整数溢出的结果。

这个问题的解决方案如下(取自here ):

...在类 StringConverter._mapper (numpy/lib/_iotools.py) 中的更改来自:

{{{
 _mapper = [(nx.bool_, str2bool, False),
            (nx.integer, int, -1),
            (nx.floating, float, nx.nan),
            (complex, _bytes_to_complex, nx.nan + 0j),
            (nx.string_, bytes, asbytes('???'))]
}}}

{{{
 _mapper = [(nx.bool_, str2bool, False),
            (nx.int64, int, -1),
            (nx.floating, float, nx.nan),
            (complex, _bytes_to_complex, nx.nan + 0j),
            (nx.string_, bytes, asbytes('???'))]
 }}}

这解决了我在numpy.genfromtxt的类似问题

请注意,作者将其描述为“临时”和“非最佳”解决方案。 但是,我使用 v2.7 没有任何副作用(还有?!)。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM