为什么我不断收到此错误“ RuntimeWarning:int_scalars中遇到溢出”

时间:2018-11-10 14:24:09

标签: python numpy

我正在尝试将二维numpy数组的所有行值和列值与显式的 for循环相乘:

product_0 = 1
product_1 = 1
for x in arr:
   product_0 *= x[0]
   product_1 *= x[1]

我意识到该产品将爆炸成为一个非常大的数字,但是根据我以前的经验,python在处理非常非常大的数字方面没有内存问题。
因此,从我可以看出来的是numpy的问题,只是我没有将硕大的产品存储在numpy数组或任何numpy数据类型中,而这仅仅是普通的python变量。

有人知道如何解决此问题吗?

使用非原位乘法没有帮助product_0 = x[0]*product_0

4 个答案:

答案 0 :(得分:0)

Python int任意精度表示,因此它们不会溢出。但是numpy是在后台使用C ++,因此最长的长符号整数具有固定的精度2^63 - 1。您的电话号码远远超过此值,平均((716-1)/2)^86507)

当您在for循环中提取x[0]时,它仍然是numpy对象。要使用python整数的全部功能,您需要将其明确分配为python int,如下所示:

product_0 = 1
product_1 = 1
for x in arr:
    t = int(x[0])
    product_0 = product_0 * t

并且它不会溢出。

在发表评论之后,使您的问题更具体,您原来的问题是为每个行/列计算数组的几何平均值。解决方法如下:

我首先生成一个与您的数组具有相同属性的数组:

arr = np.resize(np.random.randint(1,716,86507*2 ),(86507,2))

然后,计算每列/每行的几何平均值:

from scipy import stats

gm_0 = stats.mstats.gmean(arr, axis = 0)
gm_1 = stats.mstats.gmean(arr, axis = 1) 

gm_0将是一个包含xy坐标的几何平均值的数组。 gm_1包含行的几何平均值。

希望这可以解决您的问题!

答案 1 :(得分:0)

Numpy是为32位而不是64位编译的,因此虽然Python可以处理此numpy,但会为较小的值溢出,如果您要使用numpy,则建议您从源代码构建它。

编辑 经过测试

import numpy as np
x=np.abs(np.random.randn(1000,2)*1000)
np.max(x)
prod1=np.dtype('int32').type(1)
prod2=np.dtype('int32').type(1)
k=0
for i,j in x:
    prod1*=i
    prod2*=j
    k+=1
    print(k," ",prod1,prod2)

1.797693134e308 is the max value (to this many digits my numpy scalar was able to take)

如果运行此命令,您将看到numpy可以处理很大的值,但是当您说最大值为700左右时,即使1000个值,我的标量也溢出了。

关于如何解决此问题,而不是手动执行此操作,使用scipy的答案现在似乎更可行,并且能够得到答案,所以我建议您继续使用

from scipy.stats.mstats import gmean
x=np.abs(np.random.randn(1000,2)*1000)
print(gmean(x,axis=0))

答案 2 :(得分:0)

你说

  

所以我可以说这是numpy的问题,只是我没有将硕大的产品存储在numpy数组或任何numpy数据类型中,而这仅仅是普通的python变量。

您的产品可能不是NumPy数组,但正在使用NumPy数据类型。 x[0]x[1]是NumPy标量,将Python int乘以NumPy标量会得到NumPy标量。 NumPy整数的范围是有限的。

虽然从技术上讲,您可以在intx[0]上调用x[1]以获取Python整数,但最好避免使用这么大的整数。您说您要执行此乘法以计算几何平均值;在这种情况下,最好通过对数转换或从对数转换来计算几何平均值,或者使用scipy.stats.mstats.gmean,后者在内部使用对数。

答案 3 :(得分:0)

您可以使用numpy中的以下命令来实现所需的目标:

import numpy as np

product_0 = np.prod(arr.astype(np.float64))

如果您的数字足够大,它仍然可以到达np.inf,但是任何类型的情况都可能发生。