gpt4 book ai didi

python - 有条件计算的最pythonic方法是什么?

转载 作者:太空狗 更新时间:2023-10-30 03:02:09 24 4
gpt4 key购买 nike

我正在 Python/NumPy 中实现贝叶斯变点检测(如果您有兴趣,请查看 paper)。我需要计算 [a, b] 范围内数据的可能性, 其中ab可以拥有来自 1 的所有值至 n .然而,我可以在某些时候修剪计算,这样我就不必计算每一个可能性。另一方面,一些可能性被多次使用,因此我可以通过将值保存在矩阵 P[a, b] 中来节省时间。 .现在,每当我使用它时,我都会检查该值是否已经计算,但我发现这有点麻烦。它看起来像这样:

# ...
P = np.ones((n, n)) * np.inf # a likelihood can't get inf, so I use it
# as pseudo value

for a in range(n):
for b in range(a, n):

# The following two lines get annoying and error prone if you
# use P more than once

if P[a, b] == np.inf:
P[a, b] = likelihood(data, a, b)

Q[a] += P[a, b] * g[a] * Q[a - 1] # some computation using P[a, b]
# ...

我想知道,是否有更直观和 pythonic 的方式来实现这一目标,而无需 if ...每次使用 P[a, b] 之前的声明.如果不满足某些条件,则类似于自动函数调用。我当然可以制作 likelihood函数意识到它可以保存值,但是它需要某种状态(例如成为一个对象)。我想避免这种情况。

似然函数

由于在评论中被要求,我添加了似然函数。它实际上先计算共轭先验,然后计算似然。并且全部以日志表示...所以它非常复杂。

from scipy.special import gammaln
def gaussian_obs_log_likelihood(data, t, s):
n = s - t
mean = data[t:s].sum() / n

muT = (n * mean) / (1 + n)
nuT = 1 + n
alphaT = 1 + n / 2
betaT = 1 + 0.5 * ((data[t:s] - mean) ** 2).sum() + ((n)/(1 + n)) * (mean**2 / 2)
scale = (betaT*(nuT + 1))/(alphaT * nuT)

# splitting the PDF of the student distribution up is /much/ faster. (~ factor 20)
prob = 1
for yi in data[t:s]:
prob += np.log(1 + (yi - muT)**2/(nuT * scale))

lgA = gammaln((nuT + 1) / 2) - np.log(np.sqrt(np.pi * nuT * scale)) - gammaln(nuT/2)

return n * lgA - (nuT + 1)/2 * prob

虽然我使用的是 Python 2.7,但对 2.7 和 3.x 的回答都表示赞赏。

最佳答案

为此,我会使用 defaultdict 的同级(您不能直接使用 defaultdict,因为它不会告诉您缺少的 key ):

class Cache(object):
def __init__(self):
self.cache = {}

def get(self, a, b):
key = (a,b)

result = self.cache.get(key, None)
if result is None:
result = likelihood(data, a, b)
self.cache[key] = result

return result

另一种方法是在可能性 上使用缓存装饰器 as described here .

关于python - 有条件计算的最pythonic方法是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22958243/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com