Простая скользящая средняя 2D массив python - PullRequest
2 голосов
/ 30 апреля 2020

Я пытаюсь вычислить простое скользящее среднее для каждой строки двумерного массива. Данные в каждой строке представляют собой отдельный набор данных, поэтому я не могу просто вычислить SMA для всего массива, мне нужно сделать это отдельно в каждой строке. Я попытался для l oop, но он принимает окно как строки, а не отдельные значения.

Уравнение, которое я использую для вычисления SMA: a1 + a2 + ... an / n Это код, который у меня есть:

import numpy as np  


#make amplitude array
amplitude=[0,1,2,3, 5.5, 6,5,2,2, 4, 2,3,1,6.5,5,7,1,2,2,3,8,4,9,2,3,4,8,4,9,3]


#split array up into a line for each sample
traceno=5                  #number of traces in file
samplesno=6                #number of samples in each trace. This wont change.

amplitude_split=np.array(amplitude, dtype=np.int).reshape((traceno,samplesno))

#define window to average over:
window_size=3

#doesn't work for values that come before the window size. i.e. index 2 would not have enough values to divide by 3
#define limits:
lowerlimit=(window_size-1)
upperlimit=samplesno

i=window_size

for row in range(traceno):
  for n in range(samplesno):
    while lowerlimit<i<upperlimit:
      this_window=amplitude_split[(i-window_size):i] 

      window_average=sum(this_window)/window_size

      i+=1
      print(window_average)

Мой ожидаемый вывод для этих данных набор:

[[1,    2,    3.33, 4.66]
 [3,    2.66, 2.66, 3.  ]
 [4,    6,    4.33, 3.33]
 [4.33, 5,    7,    5.  ]
 [5,    5.33, 7,    5.33]]

Но я получаю:

[2.         3.         3.         4.66666667 2.66666667 3.66666667]
[2.66666667 3.66666667 5.         5.         4.         2.33333333]
[2.         4.33333333 7.         5.         6.33333333 2.33333333]

Ответы [ 2 ]

1 голос
/ 30 апреля 2020

Это должно быть легко вычислить с помощью np.correlate, используя вектор np.ones(window_size) / window_size, но, к сожалению, эта функция не может транслировать операцию корреляции. Итак, вот еще один простой способ вычислить это с np.cumsum:

import numpy as np

amplitude = [  0,   1,   2,   3, 5.5, 6,
               5,   2,   2,   4,   2, 3,
               1, 6.5,   5,   7,   1, 2,
               2,   3,   8,   4,   9, 2,
               3,   4,   8,   4,   9, 3]
traceno = 5
samplesno = 6
amplitude_split = np.array(amplitude, dtype=np.int).reshape((traceno, samplesno))
window_size = 3
# Scale down by window size
a = amplitude_split * (1.0 / window_size)
# Cumsum across columns
b = np.cumsum(a, axis=1)
# Add an initial column of zeros
c = np.pad(b, [(0, 0), (1, 0)])
# Take difference to get means
result = c[:, window_size:] - c[:, :-window_size]
print(result)
# [[1.         2.         3.33333333 4.66666667]
#  [3.         2.66666667 2.66666667 3.        ]
#  [4.         6.         4.33333333 3.33333333]
#  [4.33333333 5.         7.         5.        ]
#  [5.         5.33333333 7.         5.33333333]]
1 голос
/ 30 апреля 2020

Вы можете использовать свертку до [1, 1, ..., 1] из window_size, а затем разделить ее на window_size, чтобы получить среднее значение (нет необходимости в l oop):

from scipy.signal import convolve2d

window_average = convolve2d(amplitude_split, np.ones((1, window_size)), 'valid') / window_size)

свертка до ones в основном добавляет элементы в окно.

output:

[[1.         2.         3.33333333 4.66666667]
 [3.         2.66666667 2.66666667 3.        ]
 [4.         6.         4.33333333 3.33333333]
 [4.33333333 5.         7.         5.        ]
 [5.         5.33333333 7.         5.33333333]]
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...