【问题标题】:find common value of one matrix in another matrix在另一个矩阵中找到一个矩阵的共同值
【发布时间】:2016-06-09 14:20:51
【问题描述】:

我有一个矩阵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 中创建一个新列。

如果有任何帮助,我将不胜感激。 非常感谢。

【问题讨论】:

    标签: matlab matrix


    【解决方案1】:

    获取每行所需的列索引:

    colInd = bsxfun(@plus,Ind, -2:2)
    

    现在使用转置矩阵 (MyMatrixT = MyMatrix.') 实际上会更容易,因为我们将使用线性索引,所以我们宁愿使用

    rowIndT = colInd.';
    

    现在我们要将此Rind 转换为线性索引。这只是将总行数(原始中的列数)添加到列号的情况

    linIndT = bsxfun(@plus,rowIndT,0:size(MyMatrixT,1):size(MyMatrixT,1)*(size(MyMatrixT,2)-1))
    

    最后我们提取值并转回

    resultT = MyMatrixT(linIndT);
    result = resultT.'
    
    result =
    
        2.5100    6.3100    6.9500    4.9700    2.9100
        5.8700    6.1800    6.2300    5.2000    4.8600
       -3.5500    0.5200    3.2400   -7.7700   -8.4300
        3.4000    6.5600    7.2000    4.3000   -0.7700
    

    新列只是结果的平均值:

    mean(result,2)
    

    并将其附加到您的矩阵中

    MyMatrix = [MyMatrix, mean(result,2)]
    

    现在还有一个问题,如果最大值在边缘附近会发生什么(即,如果最大值在第 2 列中,则最大值之前的两个值未定义)。如何处理这将需要您首先定义在这种情况下您想要的行为。但是假设你想要NaN,那么我会这样做:

    colInd = bsxfun(@plus,Ind, -2:2);
    rowIndT = colInd.';
    
    %  Bound rowIndT to be between 1 and size(MyMatrixT,1)
    rowIndT(rowIndT < 1) = 1;
    rowIndT(rowIndT > size(MyMatrixT,1)) = size(MyMatrixT,1);
    
    linIndT = bsxfun(@plus,rowIndT,0:size(MyMatrixT,1):size(MyMatrixT,1)*(size(MyMatrixT,2)-1)); % You can use sub2ind instead for this step
    result = MyMatrixT(linIndT).';
    
    % Now go back and put NaNs where they are needed
    nanColInd = colInd < 1 | colInd > size(MyMatrix,2);
    result(nanColInd) = NaN;
    % Now use nanmean to ignore any NaNs when finding the mean
    MyMatrix = [MyMatrix, nanmean(result,2)]
    

    最后一件事,您可能会发现使用sub2ind 查找线性索引更直观。在那种情况下

    linIndT = bsxfun(@plus,rowIndT,0:size(MyMatrixT,1):size(MyMatrixT,1)*(size(MyMatrixT,2)-1))
    

    变成

    linIndT = sub2ind(size(MyMatrixT), rowIndT, repmat(1:size(MyMatrixT,2),size(rowIndT,1),1))
    

    【讨论】:

    • +1 非常好。所有的基础似乎都有很好的解释,做得很好。我希望 SO 允许对质量进行更多的投票。
    • 非常感谢@Dan 的帮助和解释!非常感谢。
    • @Dan 如果我只需要 NaN 时,我该如何更改代码的最后一部分,而最大值是 MyMatrix 的第一列或最后一列?相反,当最大值在第二列时,我想计算平均值,考虑最大值之前的一列,最大值和最大值之后的两列。而当最大值在倒数第二列时,我想考虑最大值之前的两列,最大值,以及最大值之后的一列。
    【解决方案2】:

    这将在最大值前后取 2 个元素的平均值并将其存储在最后一列中

    endRow = size(MyMatrix,2) + 1
    for i = 1:size(MyMatrix,1)
    
            MyMatrix(i,endRow) =  mean(MyMatrix(i,max(Ind(i)-2,0):min(Ind(i)+2,end)));
    
    
    end
    

    更新:对不起,我已经更新了最后一列中的哪些商店

    【讨论】:

    • 您可以像这样使用minmax 而不是平均0 来忽略“边缘”mean(MyMatrix(i,max(Ind(i)-2,1):min(Ind(i)+2,end))) 的元素
    • 通过该更新,您不再需要if 语句;)您也可以将endRow 替换为end+1。我认为在这种情况下使用循环是一个很好的解决方案顺便说一句,绝对更容易理解。
    • 感谢您的更正:) 我试过 end +1 它为每次迭代创建一个新列并将平均值存储在一个新列中,并且每次迭代都会增加列数(实际上这是我的第一个方法),感谢赞赏
    猜你喜欢
    • 2022-11-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-06-03
    • 2013-05-16
    • 1970-01-01
    • 2015-03-27
    相关资源
    最近更新 更多