0

我在 Matlab 中有一个问题。就是这样,我尝试对一列中不同数量的值取平均值。例如,如果我们有下面的列,

X = [1 1 2 3 4 3 8 2 1 3 5 6 7 7 5]

首先,我想先取 5 个值的平均值并绘制它们。在上述情况下,我应该收到三个可以绘制的平均值。然后一次取10个值,以此类推。我想知道您是否必须编写自定义代码来修复它。

4

6 回答 6

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 的第一个答案的修改(在编辑之前)。它使用nanmean(),取所有非 值的平均值NaN。因此,不要用 填充剩余的行,而是用zeros填充它们NaN,然后取平均值。

X = [X(:); NaN(mod(N - numel(X), N), 1)];
X_avg = nanmean(reshape(X, N, []));
于 2013-06-17T10:51:57.353 回答
2

最快的方法可能是将初始向量重新排列X到某个矩阵中,每列存储所需的平均值:

A = reshape(X, N, []);

其中N是新矩阵中所需的行数,空括号 ( []) 告诉 MATLAB 自动计算列数。然后你可以使用平均每一列mean

X_avg = mean(A);

VectorX_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稍后您可以将此代码放入循环中,计算并绘制每次迭代中不同值的平均值。

示例 #1

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

示例 #2

这是另一个例子(这次的长度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
于 2013-06-17T12:28:41.713 回答
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从列表中获取每个连续的样本并对它们进行平均,那么我相信之前的答案之一会给您想要的。

于 2013-06-17T13:47:58.710 回答
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 循环或其他方式来遍历索引。

于 2013-06-17T10:44:01.787 回答
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,依此类推,直到要从中求均值的元素数大于列中的元素数。

于 2013-06-17T10:58:18.177 回答
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 会找到函数,执行计算,返回结果。为像这样的特定操作编写自定义函数会非常有帮助 - 它不仅可以保持代码整洁,而且您只需测试一次函数...

于 2013-06-17T13:22:11.583 回答