簡體   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