OverflowError: (34, 'Result too large') in Python
OverflowError: (34, 'Result too large') in Python
我正在编写一个小脚本,用于计算和绘制给定数据的稀疏曲线。
(如维基百科所述:http://en.wikipedia.org/wiki/Rarefaction_%28ecology%29)
但是我尝试绘制值 大于 170 的函数,我不断收到以下错误:OverflowError: (34, 'Result too large')
这是一个包含一些数据的代码示例:
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()
我已经看到使用 'Decimal' 模块解决此问题的方法。我玩过它,但仍然出现错误。
有什么建议么?
问候。
编辑: 这是确切的回溯:
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')
您的异常来自这一行:
return (10**(lgn1 - (lgnk1 + lgk1)))
您尝试使用 Decimal
修复它,如下所示:
return Decimal(10**(lgn1 - (lgnk1 + lgk1)))
但这无济于事。因为 lgn1
、lgnk1
和 lgk1
是 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
,但对 Decimal
调用 log10
方法得到 Decimal
,所以:
lgn1 = sum(Decimal(ii).log10() for ii in range(1, ni))
同时,供将来参考:
I dont see how i can minimize this code further aside from erasing the lines of plotting.
嗯,首先,为什么不擦掉绘制的线条呢?
但是,更重要的是,您知道异常发生在 logchoose
函数的最后一行,并且您知道(或者可以通过添加 print ni, ki
或 运行 在调试器中)什么参数导致它引发。因此,您可以将整个事情简化为 logchoose
定义加上 print logchoose(273, 114)
(或任何参数)。
除了更短之外,这也将完全排除 numpy
和 matplotlib
,所以那些对这些库一无所知但对 Python 了解很多的人(这是绝大多数,包括比我聪明的人,dblis 和 Nimrodshn,或者至少比我聪明)可以解决你的问题。
我正在编写一个小脚本,用于计算和绘制给定数据的稀疏曲线。 (如维基百科所述:http://en.wikipedia.org/wiki/Rarefaction_%28ecology%29) 但是我尝试绘制值 大于 170 的函数,我不断收到以下错误:OverflowError: (34, 'Result too large')
这是一个包含一些数据的代码示例:
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()
我已经看到使用 'Decimal' 模块解决此问题的方法。我玩过它,但仍然出现错误。 有什么建议么? 问候。
编辑: 这是确切的回溯:
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')
您的异常来自这一行:
return (10**(lgn1 - (lgnk1 + lgk1)))
您尝试使用 Decimal
修复它,如下所示:
return Decimal(10**(lgn1 - (lgnk1 + lgk1)))
但这无济于事。因为 lgn1
、lgnk1
和 lgk1
是 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
,但对 Decimal
调用 log10
方法得到 Decimal
,所以:
lgn1 = sum(Decimal(ii).log10() for ii in range(1, ni))
同时,供将来参考:
I dont see how i can minimize this code further aside from erasing the lines of plotting.
嗯,首先,为什么不擦掉绘制的线条呢?
但是,更重要的是,您知道异常发生在 logchoose
函数的最后一行,并且您知道(或者可以通过添加 print ni, ki
或 运行 在调试器中)什么参数导致它引发。因此,您可以将整个事情简化为 logchoose
定义加上 print logchoose(273, 114)
(或任何参数)。
除了更短之外,这也将完全排除 numpy
和 matplotlib
,所以那些对这些库一无所知但对 Python 了解很多的人(这是绝大多数,包括比我聪明的人,dblis 和 Nimrodshn,或者至少比我聪明)可以解决你的问题。