11

私は値の配列を持っていますa = (2,3,0,0,4,3)

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

次の値を追加する前に、各行に .95 減衰を使用cumsumして適用する方法はありますか?numpy

4

4 に答える 4

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.")
于 2015-03-07T13:19:26.213 に答える
5

1D 配列のみを扱っている場合、scipy の利便性が不足しているか、numpy のカスタム reduce ufunc を作成していない場合、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]
于 2015-03-07T13:38:52.373 に答える
1

これは、ループを使わずに NumPy だけで簡単に実行できるとは思いません。

配列ベースのアイデアの 1 つは、行列 M_ij = .95**i * a[Nj] (N は a の要素数) を計算することです。探している数値は、エントリを対角線上で合計することによって検出されます (ij 定数を使用)。したがって、 multiple を使用できますnumpy.diagonal(…).sum()

あなたが概説した古き良きアルゴリズムはより明確で、おそらくすでにかなり高速です(そうでなければ、Cythonを使用できます)。

単一のループなしで NumPy を介してやりたいことを行うことは、私には魔法のように思えます。これをやってのけることができる人には脱帽です。

于 2015-03-07T13:13:24.863 に答える