Для вычисления скользящего среднего по n измерениям n -мерного массива ("окно" - это n размерный прямоугольник), самый простой способ - использовать свертка (см. convn
).
Вам нужно быть осторожным с краевыми эффектами , то есть когда ядро свертки (или n -мерное окно) частично выскальзывает из данных.То, что делает movmean
, усредняется только по фактическим точкам данных.Чтобы добиться такого поведения, вы можете
- вычислить сумму по ядру путем свертки с опцией
'same'
;а затем - разделите каждую запись на количество фактических точек данных, из которых она была вычислена.Это число также можно получить с помощью свертки, а именно, применяя ядро к массиву единиц.
Итак, все, что вам нужно:
my_matrix = randi(9,5,5,3); % example 3D array
sz = [3 3 2]; % 3D window size
av_matrix = convn(my_matrix, ones(sz), 'same') ... % step 1
./convn(ones(size(my_matrix)), ones(sz), 'same'); % step 2
Check :
В следующих примерах используется
>> my_matrix
my_matrix(:,:,1) =
6 8 2 1 8
4 6 7 9 8
4 5 1 4 3
5 5 8 7 9
3 6 6 4 9
my_matrix(:,:,2) =
8 8 5 3 6
8 9 6 9 1
9 5 6 2 2
1 7 4 1 2
5 4 7 4 9
my_matrix(:,:,3) =
6 5 8 6 6
1 6 8 6 1
5 5 1 6 7
1 1 2 9 8
1 2 6 1 2
С эффектами края:
>> mean(mean(mean(my_matrix(1:2,1:2,1:2))))
ans =
7.125000000000000
>> av_matrix(1,1,1)
ans =
7.125000000000000
Без эффектов края:
>> mean(mean(mean(my_matrix(1:3,1:3,1:2))))
ans =
5.944444444444445
>> av_matrix(2,2,1)
ans =
5.944444444444445