【问题标题】:mean based on maximum value of a matrix基于矩阵最大值的平均值
【发布时间】:2016-10-23 03:00:14
【问题描述】:

这篇文章是对另一篇文章的跟进:find common value of one matrix in another matrix

正如我在那里解释的,我有一个矩阵 MyMatrix 2549x13double

MyMatrix 中的几行示例:

-7.80   -4.41   -0.08   2.51    6.31    6.95    4.97    2.91    0.66    -0.92   0.31    1.24    -0.07
 4.58    5.87    6.18    6.23    5.20    4.86    5.02    5.33    3.69    1.36    -0.54   0.28    -1.20
-6.22   -3.77   1.18    2.85    -3.55   0.52    3.24    -7.77   -8.43   -9.81   -6.05   -5.88   -7.77
-2.21   -3.21   -4.44   -3.58   -0.89   3.40    6.56    7.20    4.30    -0.77   -5.09   -3.18   0.43

我已经确定了矩阵 MyMatrix 每一行的最大值如下:

[M Ind] = max(MyMatrix, [], 2); 我在 M 中获得的示例行:

6.95
6.23
3.24
7.20

现在,我想在 MyMatrix 中选择 M 中找到的最大值之前和之后的 2 个值,因为我需要计算这 5 个值的平均值。因此,在示例中,我想选择:

2.51    6.31    6.95    4.97    2.91
5.87    6.18    6.23    5.20    4.86
-3.55   0.52    3.24    -7.77   -8.43
3.40    6.56    7.20    4.30    -0.77

并用这 5 个值的平均值在 MyMatrix 中创建一个新列。

遵循@Dan 的代码,取自上一篇文章:

colInd = bsxfun(@plus,PeakInd, -2:2);
MyMatrixT = MyMatrix.';
rowIndT = colInd.';
linIndT = bsxfun(@plus,rowIndT,0:size(MyMatrixT,1):size(MyMatrixT,1)*(size(MyMatrixT,2)-1));
resultT = MyMatrixT(linIndT);
result = resultT.';
mean(result,2)
MyMatrix = [MyMatrix, mean(result,2)];

这是帖子的新部分,关于最大值接近边缘时的问题。 当最大值是 MyMatrix 的第一列或最后一列时,我想要 NaN。

相反,当最大值在第二列时,我想计算平均值,考虑最大值之前的一列、最大值和最大值之后的两列。

虽然,当最大值在倒数第二列时,我想考虑最大值之前的两列,最大值,以及最大值之后的一列。

如果您能帮助我,我将不胜感激。非常感谢!

【问题讨论】:

  • 很确定这是我的第二个代码所做的,只使用nanmean。因此,如果您的最大值在第 2 列中,那么您将得到类似 [NaN, 6,10, 4, 2] 的信息,因此 nanmean 将为您提供 [6,10,4,2] 的平均值,它使用 1 列前置和 2 列跟随最大值...
  • 关于@Dan 的评论唯一要补充的是,如果您的最大值位于第一列或最后一列,那么为了获得NaN,您只需要最后更改它即可。 (假设您要添加的列名为M2,原始矩阵的列数为N,您需要调用M2(Ind==1|Ind==N)=NaN;
  • @BillBokeey 不,我的意思是我已经在这里完全回答了stackoverflow.com/a/37705364/1011724
  • 我只是指出了这样一个事实,即如果最大值在第一列(分别是最后一列),则 OP 想要在他添加的行中添加一个 NaN。我相信您的代码会在调用 nanmean([NaN NaN value value value]) 时输出非 NaN 值

标签: matlab matrix max mean


【解决方案1】:

您可以使用min/max 来获取正确的索引,而不是使用 NaN 和 nanmean 创建二维数组:

pad = 2;
[~, Ind] = max(MyMatrix, [], 2);
minCol = max(1, Ind-pad);
maxCol = min(size(MyMatrix, 2), Ind+pad);
result = arrayfun(@(row, min_, max_) mean(MyMatrix(row, min_:max_)),...
                  (1:size(MyMatrix, 1)).', minCol, maxCol);

【讨论】:

    【解决方案2】:

    如果你有图像处理工具箱,你也可以使用padarray,例如

    B = padarray(magic(5),[0 2],NaN);
    
    B =
    
       NaN   NaN    17    24     1     8    15   NaN   NaN
       NaN   NaN    23     5     7    14    16   NaN   NaN
       NaN   NaN     4     6    13    20    22   NaN   NaN
       NaN   NaN    10    12    19    21     3   NaN   NaN
       NaN   NaN    11    18    25     2     9   NaN   NaN
    

    (...如果您没有 padarray,只需在任一侧手动添加 2 个 NaN 列)然后使用一些 bsxfun + sub2ind 我们得到所需的结果:

    pad_sz = 2;
    B = padarray(magic(5),[0 pad_sz],NaN);
    [~,I] = nanmax(B,[],2); % by using nanmax we "explicitly" say we ignore NaNs.
    colInd = bsxfun(@plus,-pad_sz:pad_sz,I);
    linearInd = sub2ind(size(B), repmat((1:5).',[1,size(colInd,2)]), colInd);
    picks = B(linearInd);
    res = nanmean(picks,2);
    % or combine the last 3 lines into:
    % res = nanmean(B(sub2ind(size(B), repmat((1:5).',[1,size(colInd,2)]), colInd)),2);
    res = res + 0./~(I == pad_sz+1 | I == size(B,2)-pad_sz); %add NaN where needed.
    

    【讨论】:

    • 感谢您的回复。但是,我希望 NaN 表示平均值,仅当最大值位于第一列或最后一列时(如果最大值位于倒数第二列或倒数第二列也可以)。
    猜你喜欢
    • 1970-01-01
    • 2013-09-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-12-02
    • 2012-10-14
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多