MATLAB:获取按第一列排序的前n个值的平均值

时间:2013-04-12 11:27:08

标签: matlab mean

我有一个21128x9细胞的细胞阵列,按第1列排序,例如(大规模简化):

    A=[1 3; 1 5; 1 3; 2 1; 2 2; 2 3; 3 5; 3 5]

    A =

         1     3
         1     5
         1     3
         2     1
         2     2
         2     3
         3     5
         3     5

其中第1列中的某些值比其他值重复。

我想要做的是获取第一列的每个值的第二列的平均值,但仅针对前两个值。

    ans= 1 4
         2 1.5
         3 5

我正在尝试使用这个基本功能

    means = accumarray(A(:,1) ,A(:,2),[],@mean);

但我不知道如何让它只适用于每组的前两个值。我假设我需要一个 for 循环,类似于:

    for ;
        means = accumarray(A(:,1) ,A(:,2),[],@mean);
    end

我不知道 需要什么。

1 个答案:

答案 0 :(得分:4)

accumarray将一个向量传递给匿名函数,所以你可以这样做,例如:

A = [1 3; 1 5; 1 3; 2 1; 2 2; 2 3; 3 5; 3 5];
maxAvgs = 3;
accumarray(A(:, 1), A(:, 2), [], @(x)mean(x(1:min(length(x), maxAvgs))))

ans =

3.6667
2.0000
5.0000

maxAvgs = 2;
accumarray(A(:, 1), A(:, 2), [], @(x)mean(x(1:min(length(x), maxAvgs))))

ans =

4.0000
1.5000
5.0000

每当您不确定涉及匿名函数的情况时,您可以将您的匿名函数编写为@(varargin)disp(varargin);这将显示输入参数。在这种情况下,这不起作用,因为accumarray 需要您传递的函数返回一个参数。但是,您仍然可以将其设置为匿名函数并从脚本运行代码;在编辑器窗口的行上设置一个断点,确保为断点的位置选择“匿名函数”。

修改

  

在我的实际数据中,有些有60个值,有些有120个,有些有180个。   作为补充,是否有可能然后运行平均函数   下一批价值(即价值61-120,然后是121-180)?

要在评论中执行您的建议,我建议您创建一个函数splitMean并将其传递给accumarray

function y = splitMean(x, n)
% If length of x doesn't divide by n, the extra elements will be averaged
% separately
extra = mod(length(x), n);
M = length(x)-extra;

meanData = reshape(x(1:M), M / n, n);

extraMean = [];
if extra > 0, extraMean = mean(x(M+1:end)); end
if ~isempty(meanData)
    y = {[mean(meanData).'; extraMean]};
else
    y = {extraMean};
end

然后,

maxAvgs = 2;
cell2mat(accumarray(A(:, 1), A(:, 2), [], @(x)splitMean(x, maxAvgs)))

ans =

4.0000
3.0000
1.5000
3.0000
5.0000

%%% Without the cell2mat:

ans =

[2x1 double]
[2x1 double]
[         5]

通过这种方式,您可以获得每个组可以同时提供的所有方法集。请注意cell2mat。如果您希望它们按组索引拆分,则删除它,您将获得一个单元格数组。