给定2D numpy
数组A
和1D数组c
,我想用条目计算2D数组B
B[i, j] = scipy.special.logsumexp(np.append(c, A[i, j]))
。
我可以用矢量化方式而不是使用双循环吗?
答案 0 :(得分:2)
为什么不简单地使用np.log(np.sum(np.exp(c)) + np.exp(A))
?
[根据Paul Panzer的评论更新]
_c = np.broadcast_to(c, (*A.shape, *c.shape))
B = scipy.special.logsumexp(np.append(_c, A[...,np.newaxis], axis=-1), axis=-1)
答案 1 :(得分:2)
要模仿logsumexp
的行为,您需要做的就是在取max
之前减去其参数的exp, sum, log
(检查source code)然后重新在最后添加它。因此,您可以执行以下操作:
>>> import numpy as np
>>> from scipy import special
>>>
>>> A = np.random.uniform(900, 1100, (4, 4))
>>> c = np.random.uniform(950, 1050, (7,))
>>>
>>> cm = np.max(c)
>>> mask = A > cm
>>> B = np.empty_like(A)
>>> B[mask] = A[mask] + np.log(np.exp(np.subtract.outer(cm, A[mask])).sum(axis=-1) + 1)
>>> B[~mask] = cm + np.log(np.exp(c - cm).sum() + np.exp(A[~mask] - cm))
>>>
# compute via logsumexp for reference
>>> cA = np.empty((8, 4, 4))
>>> cA[:-1] = c[:, None, None]
>>> cA[-1] = A
>>> special.logsumexp(cA, axis=0)
array([[ 1048.88855012, 1048.88854955, 1069.83524808, 1048.88854955],
[ 1048.88854955, 1048.88854955, 1048.88877212, 1048.93142975],
[ 1048.88854955, 1067.59166572, 1048.88854955, 1069.78737913],
[ 1048.88854955, 1048.88854955, 1098.61910373, 1072.76058998]])
>>> B
array([[ 1048.88855012, 1048.88854955, 1069.83524809, 1048.88854955],
[ 1048.88854955, 1048.88854955, 1048.88877212, 1048.93142975],
[ 1048.88854955, 1067.59166572, 1048.88854955, 1069.78737914],
[ 1048.88854955, 1048.88854955, 1098.61910374, 1072.76058999]])