我有一个经常出现的问题,我有两个相同长度的数组:一个有值,一个有动态衰减因子;并且希望计算每个位置的衰减累积和的向量。使用Python循环来表达所需的递归,我们有以下内容:
c = np.empty_like(x)
c[0] = x[0]
for i in range(1, len(x)):
c[i] = c[i-1] * d[i] + x[i]
字符串
Python代码非常清晰可读,但速度明显变慢。我可以通过使用Numba进行JIT编译,或者使用Cython进行预编译来解决这个问题。如果折扣因子是一个固定的数字(事实并非如此),我可以使用SciPy的信号库并执行lfilter
(参见https://stackoverflow.com/a/47971187/1017986)。
有没有一种更“Numpythonic”的方式来表达这一点,而不牺牲清晰度或效率?
1条答案
按热度按时间5jvtdoz21#
从数学上讲,这是一个一阶变系数非齐次递推关系。
请注意,系数(在您的情况下,
d[1:]
中的值)必须不同于0。下面是一种使用NumPy函数求解递归关系的方法。请注意,
d[0]
被设置为1,因为您的算法没有使用它,我需要它为1。在这个解决方案中,正如您所看到的,c
中的值不依赖于c
中以前的值。即,c[i]
不依赖于c[i-1]
。字符串
让我们举个例子。这里我定义了两个函数,一个用你的代码计算递归关系,另一个使用NumPy:
型
以下是一些用法示例:
型
如果你对这个答案背后的数学细节感兴趣(这超出了这里的范围),请查看this维基百科页面。
编辑
这个解决方案虽然在数学上是正确的,但在计算过程中可能会引入数值问题(因为
numpy.cumprod
函数),特别是如果d
包含可能接近0的值。