NumPy中的cumsum功能可以在添加时衰减吗?

时间:2015-03-07 12:55:05

标签: python arrays numpy cumsum

我有一组值a = (2,3,0,0,4,3)

y=0
for x in a:
  y = (y+x)*.95

有没有办法在cumsum中使用numpy并在添加下一个值之前将.95衰减应用到每一行?

4 个答案:

答案 0 :(得分:8)

你要求一个简单的IIR Filter。 Scipy的lfilter()是为此而制作的:

import numpy as np
from scipy.signal import lfilter

data = np.array([2, 3, 0, 0, 4, 3], dtype=float)  # lfilter wants floats

# Conventional approach:
result_conv = []
last_value = 0
for elmt in data:
    last_value = (last_value + elmt)*.95
    result_conv.append(last_value)

# IIR Filter:
result_IIR = lfilter([.95], [1, -.95], data)

if np.allclose(result_IIR, result_conv, 1e-12):
    print("Values are equal.")

答案 1 :(得分:4)

如果您只处理一维数组,那么缺乏scipy便利或编写自定义reduce ufunc for numpy,那么在Python 3.3+中,您可以使用itertools.accumulate,例如:

from itertools import accumulate

a = (2,3,0,0,4,3)
y = list(accumulate(a, lambda x,y: (x+y)*0.95))
# [2, 4.75, 4.5125, 4.286875, 7.87253125, 10.3289046875]

答案 2 :(得分:2)

Numba提供了vectorize函数的简便方法,创建了universal function(因此提供了ufunc.accumulate):

import numpy
from numba import vectorize, float64

@vectorize([float64(float64, float64)])
def f(x, y):
    return 0.95 * (x + y)

>>> a = numpy.array([2, 3, 0, 0, 4, 3])
>>> f.accumulate(a)
array([  2.        ,   4.75      ,   4.5125    ,   4.286875  ,
         7.87253125,  10.32890469])

答案 3 :(得分:1)

我不认为单独使用NumPy可以轻松完成,不使用循环。

一个基于阵列的想法是计算矩阵M_ij = .95 ** i * a [N-j](其中N是a中元素的数量)。您正在寻找的数字是通过对角求和条目(使用i-j常数)找到的。您可以使用多个numpy.diagonal(…).sum()

你概述的好旧算法已经更清晰,可能已经非常快(否则你可以使用Cython)。

在没有单个循环的情况下通过NumPy做你想做的事听起来像巫术。向任何可以解决此问题的人致敬。