Python 如何计算数字数组的对数阶乘

Python 如何计算数字数组的对数阶乘,python,arrays,performance,numpy,Python,Arrays,Performance,Numpy,要计算的数量为log(k!),其中k可能为4000或更高,但当然,log将进行补偿。我试着计算相同的sum(log(k)) 因此,我得到了一个包含整数的大数组,我想高效地计算和(log(k))。这是我的尝试: integers = np.asarray([435, 535, 242,]) score = np.sum(np.log(np.arange(1,integers+1))) 这是可行的,只是np.arange会为每个整数生成不同大小的数组,所以当我运行它时,它会给我一个错误(应该是这

要计算的数量为
log(k!)
,其中
k
可能为4000或更高,但当然,log将进行补偿。我试着计算相同的
sum(log(k))

因此,我得到了一个包含整数的大数组,我想高效地计算
和(log(k))
。这是我的尝试:

integers = np.asarray([435, 535, 242,])

score = np.sum(np.log(np.arange(1,integers+1)))
这是可行的,只是
np.arange
会为每个整数生成不同大小的数组,所以当我运行它时,它会给我一个错误(应该是这样的)

使用
for
循环可以轻松解决此问题,如下所示:

scores = []
for i in range(integers.shape[0]):
    score = np.sum(np.log(np.arange(1,integer[i]+1)))
    scores.append(score)
但那太慢了。我的实际
整数
有数百万个值需要计算


是否有一个基本上不需要for循环的高效实现?我正在考虑一个
lambda
函数或类似的东西,但我不确定如何应用它。感谢您的帮助

那math.lgama呢?Gamma函数是阶乘函数,是Gamma的对数

您不需要计算阶乘,然后记录

在SciPy中也有

代码,Python 3.9 x64 Win 10

import numpy as np
from scipy.special import gammaln

startf = 1 # start of factorial sequence
stopf  = 400 # end of of factorial sequence

q = gammaln(range(startf+1, stopf+1)) # n! = G(n+1)
print(q)

在我看来很合理

您可以使用以下内容进行矢量化:

mi = integers.max()
ls = np.log(np.arange(2, mi + 1))
到目前为止有两个优化:您只需要最大范围,因为其他数字都包含在其中,而不需要
log(1)

现在,我们来计算累计总和:

cs = np.cumsum(ls)
可以直接为所需元素编制索引:

result = cs[integers - 2]
如果这是您需要多次执行的操作,并且您知道上限,那么一旦您将
cs
预计算到上限,此解决方案将比使用
math.lgmamma
scipy.special.gammaln
快得多

如果这是一次通话,以下是必须的一行:

np.cumsum(np.log(np.arange(2, np.max(integers))))[integers - 2]
如果内存是一个问题,您可以就地执行大多数操作(我认为这也会使它们更快):


是的,那正是我想要的。谢谢大家!@Schach21用SciPy的示例代码更新了答案,由于矢量化,可能会更快。为什么要求和?@MadPhysicast啊,明白了,我错了。帖子更正,谢谢you@Schach21请注意,
lgama
通常在数值上比手动计算
log(n!)
更稳定(即更准确)。这是一个非常好的解决方案!很高兴你喜欢:)
mi = integers.max()
cs = np.arange(2, mi + 1)
np.cumsum(np.log(cs, out=cs), out=cs)