numpy数组中的整数溢出

时间:2009-12-28 17:56:08

标签: python numpy

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]]

4 个答案:

答案 0 :(得分:17)

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

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

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

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

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

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

有关numpy邮件列表的讨论,请参阅http://mail.scipy.org/pipermail/numpy-discussion/2009-April/041691.html

答案 1 :(得分:4)

python整数没有这个问题,因为它们溢出时会自动升级到python长整数。

所以如果你设法溢出int64,一个解决方案就是在numpy数组中使用python int:

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

答案 2 :(得分:2)

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

答案 3 :(得分:0)

此问题的解决方案如下(取自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没有副作用(但是?!)。