我在Matlab中有一个问题。就是这样,我试着取一列中不同数量的值的平均值。例如,如果我们有下面的列,
X = [1 1 2 3 4 3 8 2 1 3 5 6 7 7 5]
首先,我想首先取5个值的平均值并绘制它们。在上面的例子中,我应该得到三个我可以绘制的平均值。然后一次取10个值,依此类推。 我想知道你是否必须编写自定义代码来修复它。
答案 0 :(得分:2)
这应该可以解决问题:
对于选定的N
(您想要取的平均值的数量):
N = 5;
mean_vals = arrayfun(@(n) mean(X(n-1+(1:N))),1:N:length(X))
注意:这不会检查Index exceeds matrix dimensions
。
如果你想跳过最后一个数字,这应该有效:
mean_vals = arrayfun(@(n) mean(X(n-1+(1:N))),1:N:(length(X)-mod(length(X),N)));
添加剩余值:
if mod(length(X),N) ~= 0
mean_vals(end+1) = mean(X(numel(X)+1-mod(length(X),N):end))
end
更新:这是Eitan's第一个答案(在编辑之前)的修改。它使用nanmean()
,它取所有非NaN
值的均值。因此,不要使用zeros
填充剩余的行,而是使用NaN
填充它们,然后选择均值。
X = [X(:); NaN(mod(N - numel(X), N), 1)];
X_avg = nanmean(reshape(X, N, []));
答案 1 :(得分:2)
最快的方法可能是将初始向量X
重新排列到某个矩阵中,每列存储所需的平均值:
A = reshape(X, N, []);
其中N
是新矩阵中所需的行数,空括号([]
)告诉MATLAB自动计算列数。然后,您可以使用mean
平均每列:
X_avg = mean(A);
Vector X_avg
存储结果。这可以在一行中完成,如下所示:
X_avg = mean(reshape(X, N, []));
请注意,X
中的元素数量必须可以被N
整除,否则您必须先填充它(例如带有零),或者分别处理“剩余”尾部元素:
tail = mod(numel(X), N);
X_avg = mean(reshape(X(1:numel(X) - tail), N, [])); %// Compute average values
X_avg(end + 1) = mean(X(end - tail + 1:end)); %// Handle leftover elements
稍后您可以将此代码放在一个循环中,计算并绘制每次迭代中N
的不同值的平均值。
X = [1 1 2 3 4 3 8 2 1 3 5 6 7 7 5];
N = 5;
tail = mod(numel(X), N);
X_avg = mean(reshape(X(1:numel(X) - tail), N, []))
X_avg(end + 1) = mean(X(end - tail + 1:end))
结果是:
X_avg =
2.2000 3.4000 6.0000
这是另一个例子(这次X
的长度不能被N
整除):
X = [1 1 2 3 4 3 8 2 1 3 5 6 7 7 5];
N = 10;
tail = mod(numel(X), N);
X_avg = mean(reshape(X(1:numel(X) - tail), N, []))
X_avg(end + 1) = mean(X(end - tail + 1:end))
结果是:
X_avg =
2.8000 6.0000
答案 2 :(得分:0)
如果您发布了一些代码并指出了哪些代码无效,那将会很有帮助。
作为第一个指针。如果
X = [1 1 2 3 4 3 8 2 1 3 5 6 7 7 5]
你感兴趣的5个块中的三个手段是
mean(X(1:5))
mean(X(6:10))
mean(X(11:15))
你必须想出一个for循环或者其他一些方法来迭代索引。
答案 3 :(得分:0)
我认为你想要这样的东西(我有一段时间没有使用Matlab,我希望语法是正确的):
X = [1 1 2 3 4 3 8 2 1 3 5 6 7 7 5],
currentAmount=5,
block=0,
while(numel(X)<=currentAmount)
while(numel(X)<=currentAmount+block*currentAmount)
mean(X(block*currentAmount+1:block*currentAmount+currentAmount));
block =block+1;
end;
currentAmount = currentAmount+5;
block=0;
end
此代码首先循环遍历所有元素,一次计算5个元素的平均值。然后,它将扩展到10个元素。然后到15,依此类推,直到你想要制作平均数的元素数量大于列中元素的数量。
答案 4 :(得分:0)
如果你需要做很多这样的操作,可能值得为它编写自己的函数。我建议使用@ EitanT的基本思想:填充数据,重新整形,取每列的平均值。但是,我建议不要在末尾包括零填充数字,而是分别取“分散”数据点的平均值:
function m = meanOfN(x, N)
% function m = meanOfN(x, N)
% create groups of N elements of vector x
% and return their mean
% if numel(x) is not a multiple of N, the last value returned
% will be for fewer than N elements
Nf = N * floor( numel( x ) / N ); % largest multiple of N <= length of x
xr = reshape( x( 1:Nf ), N, []);
m = mean(xr);
if Nf < N
m = [m mean( x( Nf + 1:end ) )];
end
此函数将完全返回您要求的内容:在N = 5的15元素向量的情况下,它返回3个值。当输入向量的大小不是N的倍数时,返回的最后一个值将是“剩下的平均值”。
通常当你需要取一组数字的平均值时,它就是感兴趣的“运行平均值”。因此,您可能需要
,而不是获取[mean(x(1:5)) mean(x(6:10)) mean(11:15))]
m(1) = mean(x(1:N));
m(2) = mean(x(2:N+1));
m(3) = mean(x(3:N+2));
...etc
这可以通过使用一个向量的简单卷积来实现;为了完整性,这里有一种可能的编码方式:
function m = meansOfN(x, n)
% function m = meansOfN(x, n)
% taking the running mean of the values in x
% over n samples. Returns a row vector of size (sizeof(x) - n + 1)
% if numel(x) < n, this returns an empty matrix
mv = ones(N,1) / N; % vector of ones, normalized
m = convn(x(:), mv, 'valid'); % perform 1D convolution
在路径中使用这两个函数(将它们分别保存在名为meanOfN.m
和meansOfN.m
的文件中),您可以执行任何操作。在任何程序中,您都可以编写
myMeans = meanOfN(1:30, 5);
myMeans2 = meansOfN(1:30, 6);
等。 Matlab将找到该函数,执行计算,返回结果。为这样的特定操作编写自定义函数非常有用 - 不仅可以保持代码干净,而且只需要测试一次函数......
答案 5 :(得分:0)
如果您希望在K
维向量中平均N
个随机样本,那么您可以使用:
N = length(X);
K = 20; % or 10, or 30, or any integer less than or equal to N
indices = randperm(N, K); % gives you K random indices from the range 1:N
result = mean(X(indices)); % averages the values of X at the K random
% indices from above
稍微紧凑的形式是:
K = 20;
result = mean(X(randperm(length(X), K)));
如果您只想从列表中取出每个K
个连续样本并对其进行平均,那么我相信之前的答案之一会给您所需的内容。