gpt4 book ai didi

matlab - 我如何(有效地)计算向量的移动平均值?

转载 作者:太空宇宙 更新时间:2023-11-03 19:25:48 25 4
gpt4 key购买 nike

我有一个向量,我想计算它的移动平均值(使用宽度为 5 的窗口)。

例如,如果有问题的向量是[1,2,3,4,5,6,7,8],那么

  • 结果向量的第一个条目应该是 [1,2,3,4,5] 中所有条目的总和(即 15);<
  • 结果向量的第二个条目应该是 [2,3,4,5,6] 中所有条目的总和(即 20);<
  • 等等

最后,生成的向量应该是[15,20,25,30]。我该怎么做?

最佳答案

conv函数就在你的巷子里:

>> x = 1:8;
>> y = conv(x, ones(1,5), 'valid')

y =
15 20 25 30

基准

三个答案,三种不同的方法...这是一个使用 timeit 的快速基准测试(不同的输入大小,固定的窗口宽度为 5) ;如果您认为它需要改进,请随时在其中(在评论中)戳洞。

conv 成为最快的方法;它的速度大约是 coin's approach (using filter) 的两倍, 大约是 Luis Mendo's approach (using cumsum) 的四倍.

enter image description here

这是另一个基准(固定输入大小为 1e4,不同的窗口宽度)。在这里,Luis Mendo's cumsum approach显然是赢家,因为它的复杂性主要由输入的长度决定,并且对窗口的宽度不敏感。

enter image description here

结论

总而言之,你应该

  • 如果您的窗口相对较小,请使用conv 方法,
  • 如果您的窗口相对较大,请使用 cumsum 方法。

代码(用于基准测试)

function benchmark

clear all
w = 5; % moving average window width
u = ones(1, w);
n = logspace(2,6,60); % vector of input sizes for benchmark
t1 = zeros(size(n)); % preallocation of time vectors before the loop
t2 = t1;
th = t1;

for k = 1 : numel(n)

x = rand(1, round(n(k))); % generate random row vector

% Luis Mendo's approach (cumsum)
f = @() luisMendo(w, x);
tf(k) = timeit(f);

% coin's approach (filter)
g = @() coin(w, u, x);
tg(k) = timeit(g);

% Jubobs's approach (conv)
h = @() jubobs(u, x);
th(k) = timeit(h);
end

figure
hold on
plot(n, tf, 'bo')
plot(n, tg, 'ro')
plot(n, th, 'mo')
hold off
xlabel('input size')
ylabel('time (s)')
legend('cumsum', 'filter', 'conv')

end

function y = luisMendo(w,x)
cs = cumsum(x);
y(1,numel(x)-w+1) = 0; %// hackish way to preallocate result
y(1) = cs(w);
y(2:end) = cs(w+1:end) - cs(1:end-w);
end

function y = coin(w,u,x)
y = filter(u, 1, x);
y = y(w:end);
end

function jubobs(u,x)
y = conv(x, u, 'valid');
end

function benchmark2

clear all
w = round(logspace(1,3,31)); % moving average window width
n = 1e4; % vector of input sizes for benchmark
t1 = zeros(size(n)); % preallocation of time vectors before the loop
t2 = t1;
th = t1;

for k = 1 : numel(w)
u = ones(1, w(k));
x = rand(1, n); % generate random row vector

% Luis Mendo's approach (cumsum)
f = @() luisMendo(w(k), x);
tf(k) = timeit(f);

% coin's approach (filter)
g = @() coin(w(k), u, x);
tg(k) = timeit(g);

% Jubobs's approach (conv)
h = @() jubobs(u, x);
th(k) = timeit(h);
end

figure
hold on
plot(w, tf, 'bo')
plot(w, tg, 'ro')
plot(w, th, 'mo')
hold off
xlabel('window size')
ylabel('time (s)')
legend('cumsum', 'filter', 'conv')

end

function y = luisMendo(w,x)
cs = cumsum(x);
y(1,numel(x)-w+1) = 0; %// hackish way to preallocate result
y(1) = cs(w);
y(2:end) = cs(w+1:end) - cs(1:end-w);
end

function y = coin(w,u,x)
y = filter(u, 1, x);
y = y(w:end);
end

function jubobs(u,x)
y = conv(x, u, 'valid');
end

关于matlab - 我如何(有效地)计算向量的移动平均值?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26981478/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com