Python中的日志计算
作者:互联网
我想要计算类似的东西:
其中f(i)是一个函数,它在[-1,1]中为{1,2,…,5000}中的任何i返回实数.
显然,和的结果在[-1,1]中,但是当我似乎无法使用直接编码在Python中计算它时,0.55000变为0并且梳子(5000,2000)变为inf ,这导致计算的总和变成NaN.
所需的解决方案是使用双面登录.
那是使用身份a×b = 2log(a)log(b),如果我可以计算log(a)和log(b)我可以计算总和,即使a很大而b几乎为0.
所以我想我要问的是,如果有一种简单的计算方法
log2(scipy.misc.comb(5000,2000))
所以我可以简单地计算我的总和
sum([2**(log2comb(5000,i)-5000) * f(i) for i in range(1,5000) ])
@ abarnert的解决方案,同时为5000图工作,通过提高计算梳子的精度来解决问题.这适用于此示例,但不会扩展,因为如果不是5000而我们需要1e7,所需的内存将显着增加.
目前,我正在使用一种丑陋的解决方法,但保持低内存消耗:
log2(comb(5000,2000)) = sum([log2 (x) for x in 1:5000])-sum([log2 (x) for x in 1:2000])-sum([log2 (x) for x in 1:3000])
有没有办法在可读的表达式中这样做?
解决方法:
总和
f是相对于binomial distribution的期望,其中n = 5000且p = 0.5.
您可以使用scipy.stats.binom.expect计算:
import scipy.stats as stats
def f(i):
return i
n, p = 5000, 0.5
print(stats.binom.expect(f, (n, p), lb=0, ub=n))
# 2499.99999997
还要注意,当n变为无穷大时,p固定,二项分布approaches the normal distribution具有平均np和方差np *(1-p).因此,对于大n,您可以改为计算:
import math
print(stats.norm.expect(f, loc=n*p, scale=math.sqrt((n*p*(1-p))), lb=0, ub=n))
# 2500.0
标签:large-data,python,scipy 来源: https://codeday.me/bug/20191007/1867288.html