Python中的OverflowError:(34,'结果太大')

时间:2015-04-13 07:28:04

标签: python matplotlib

我正在编写一个小脚本,用于计算和绘制给定数据上的稀疏曲线。 (如维基百科中所述:http://en.wikipedia.org/wiki/Rarefaction_%28ecology%29) 但我尝试绘制值大于170 的函数我不断收到以下错误:OverflowError:(34,'结果太大')

以下是包含一些数据的代码示例:

import numpy as np
import math
import matplotlib.pyplot as plt
import decimal

def pltCurve():
    data = [[367, 172, 503, 1404, 8, 83, 7, 2, 7, 1, 0, 6, 31, 0, 6, 40, 0, 18, 132, 41, 1, 2, 15, 1, 0, 10, 0, 63, 59, 3, 0, 7, 9, 9, 4, 0, 2, 0, 23, 20, 4, 0, 0, 1, 11, 55, 0, 0, 1, 1, 0, 1, 4, 11, 0, 10, 6, 0, 4, 0, 443, 2, 49, 29, 0, 5, 6, 0, 0, 1, 0, 0, 0, 0, 0, 32, 0, 1, 14, 1, 0, 1, 3, 1, 1, 0, 7, 0, 2, 32, 2, 1, 55, 0, 21, 1, 7, 2, 0, 0, 0, 0, 0, 0, 0, 1, 76, 5, 9, 28, 1, 0, 72, 0, 0, 0, 0, 61, 6, 5, 0, 5, 2, 0, 1, 9, 1, 0, 1, 1, 1, 1, 1, 1, 34, 28, 1, 1, 1, 3, 3, 0, 0, 1, 0, 0, 3, 1, 3, 55, 19, 18, 87, 0, 1, 2, 6, 15, 10, 1, 2]]

    for d in range(len(data)):
        x = np.arange(1,170 , 10)
        y = computeFn(d,x)
        #plt.plot(x,y)
        plt.errorbar(x,y,yerr=0.95)

    plt.show()

def computeFn(i, n):
    N = 4467
    res = []
    r = Decimal(0)
    numOfGroups = 161
    data = [[367, 172, 503, 1404, 8, 83, 7, 2, 7, 1, 0, 6, 31, 0, 6, 40, 0, 18, 132, 41, 1, 2, 15, 1, 0, 10, 0, 63, 59, 3, 0, 7, 9, 9, 4, 0, 2, 0, 23, 20, 4, 0, 0, 1, 11, 55, 0, 0, 1, 1, 0, 1, 4, 11, 0, 10, 6, 0, 4, 0, 443, 2, 49, 29, 0, 5, 6, 0, 0, 1, 0, 0, 0, 0, 0, 32, 0, 1, 14, 1, 0, 1, 3, 1, 1, 0, 7, 0, 2, 32, 2, 1, 55, 0, 21, 1, 7, 2, 0, 0, 0, 0, 0, 0, 0, 1, 76, 5, 9, 28, 1, 0, 72, 0, 0, 0, 0, 61, 6, 5, 0, 5, 2, 0, 1, 9, 1, 0, 1, 1, 1, 1, 1, 1, 34, 28, 1, 1, 1, 3, 3, 0, 0, 1, 0, 0, 3, 1, 3, 55, 19, 18, 87, 0, 1, 2, 6, 15, 10, 1, 2]]
    #print N
    for k in n:
        r = (sum((logchoose(N-N_i,k)) for N_i in data[i]))*(logchoose(N,k))**-1
        r = Decimal(numOfGroups) - r
        print r # Debug
        res.append(r)
    return res

def logchoose(ni, ki):

    """
    :rtype : N choose K Function
    """
    try:
        lgn1 = sum(math.log10(ii) for ii in range(1,ni))
        lgk1 = sum(math.log10(ii) for ii in range(1,ki))
        lgnk1 = sum(math.log10(ii) for ii in range(1,ni-ki+1))
    except ValueError:
        #print ni,ki
        raise ValueError
    #print 10**(lgn1 - (lgnk1 + lgk1))
    return Decimal((10**(lgn1 - (lgnk1 + lgk1))))


pltCurve()

我已经看过使用“十进制”'解决这个问题的方法。模块。我玩过它但仍然出现了错误。 有什么建议? 问候。

编辑:以下是完全追溯:

    Traceback (most recent call last):
  File "C:\Users\user\Documents\Rarefactor\test.py", line 48, in <module>
    pltCurve()
  File "C:\Users\user\Documents\Rarefactor\test.py", line 11, in pltCurve
    y = computeFn(d,x)
  File "C:\Users\user\Documents\Rarefactor\test.py", line 26, in computeFn
    r = (sum((logchoose(N-N_i,k)) for N_i in data[i]))*(logchoose(N,k))**-1
  File "C:\Users\user\Documents\Rarefactor\test.py", line 26, in <genexpr>
    r = (sum((logchoose(N-N_i,k)) for N_i in data[i]))*(logchoose(N,k))**-1
  File "C:\Users\user\Documents\Rarefactor\test.py", line 45, in logchoose
    return (10**(lgn1 - (lgnk1 + lgk1)))
OverflowError: (34, 'Result too large')

1 个答案:

答案 0 :(得分:0)

您的例外来自此行:

return (10**(lgn1 - (lgnk1 + lgk1)))

您尝试使用Decimal这样修复它:

return Decimal(10**(lgn1 - (lgnk1 + lgk1)))

但这不会有帮助。由于lgn1lgnk1lgk1的值为float,因此您尝试使用float值进行算术运算,然后转换结果完成后Decimal。因为float算术溢出,所以它永远不会转换。

您需要做的是首先在Decimal值上进行算术运算。例如:

lgn1 = Decimal(sum(math.log10(ii) for ii in range(1,ni)))
lgk1 = Decimal(sum(math.log10(ii) for ii in range(1,ki)))
lgnk1 = Decimal(sum(math.log10(ii) for ii in range(1,ni-ki+1)))

现在,当你这样做时:

return (10**(lgn1 - (lgnk1 + lgk1)))

...您已获得Decimal算术,而不是float,并且它不会溢出(只要您的Decimal上下文对这些数字足够大,当然)。

但是你可能希望尽可能地将Decimal推到尽可能高的链上。在这种情况下,整数上只有一个级别向上调用math.log10会为您提供float,但在log10上调用Decimal方法会为您提供一个Decimal,所以:

lgn1 = sum(Decimal(ii).log10() for ii in range(1, ni))

同时,供将来参考:

  

除了删除绘图线之外,我不知道如何进一步减少此代码。

那么,首先,为什么不删除那些绘图线?

但是,更重要的是,你知道异常发生在logchoose函数的最后一行,你知道(或者可以知道,例如,添加print ni, ki或运行调试器)什么参数导致它引发。所以你可以将整个事情减少到logchoose定义加上print logchoose(273, 114)(或者无论参数是什么)。

除了缩短之外,这也完全取消了numpymatplotlib,因此对这些库一无所知但对Python有很多了解的人(绝大多数,包括比我聪明的人,dbliss和Nimrodshn,或者至少比我更聪明)可以解决你的问题。