【问题标题】:Why do I keep getting this error 'RuntimeWarning: overflow encountered in int_scalars'为什么我不断收到此错误“RuntimeWarning:int_scalars 中遇到溢出”
【发布时间】:2019-04-13 20:37:27
【问题描述】:

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

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

【问题讨论】:

    标签: python numpy


    【解决方案1】:

    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 包含行的几何平均值。

    希望这能解决您的问题!

    【讨论】:

    • 操作者希望他的阵列产品是独立的,不需要加入它们
    • 文字是“所有的价值”
    • 使用 np.shape() 我的数组的形状为 (86507,2)。它们是 (x,y) 方式的整数坐标,我试图获得所有 x 的几何平均值y 分别是数组中的任何值都不应超过 716,因此唯一应该大的数字是名为 product 的非 numpy 普通 python 变量。
    【解决方案2】:

    你说

    所以据我所知,这是 numpy 的一个问题,除了我没有将巨大的产品存储在 numpy 数组或任何 numpy 数据类型中,它只是一个普通的 python 变量。

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

    虽然从技术上讲,您可以在 x[0]x[1] 上调用 int 来获得 Python int,但最好避免需要如此大的 int。您说您正在尝试执行此乘法来计算几何平均值;在这种情况下,最好通过与对数之间的转换来计算几何平均值,或者使用scipy.stats.mstats.gmean,它在后台使用对数。

    【讨论】:

      【解决方案3】:

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

      【讨论】:

      • 但我什至没有在我的 numpy 数组中存储任何大数字,程序中唯一的大数字是产品,除了产品只是一个普通的 python 变量而不是 numpy 数据类型
      • 你能尝试找出从哪个值开始溢出?
      • 我在我的 for 循环中放了一个 print(product_0) 语句,一旦它运行,它就会为 product_0 *= x[0]product_1 *= x[1 行给出上述错误,之后它首先打印越来越大的数字和然后是负数,然后是正数,这个循环重复一段时间,然后打印一大堆零。最后一个非零数是-2147483648,但奇怪的是不应该有负数数组实际上是通过np.argwhere(arr1)获得的所有非零值的坐标,其中arr1是一个单独的numpy数组。
      【解决方案4】:

      你可以在 numpy 中使用以下命令实现你想要的:

      import numpy as np
      
      product_0 = np.prod(arr.astype(np.float64))
      

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-11-28
        • 2017-07-24
        • 2019-01-09
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多