2016-06-08 78 views
1

我已经从一个矩阵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); 

条实施例线I得到中号

6.95 
6.23 
3.24 
7.20 

现在,我想在中号发现2个值之前和最大值之后在myMatrix的选择,因为我将需要以计算平均这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的新列。

我将不胜感激任何帮助。 非常感谢。

回答

5

每行获取所需的列索引:

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)) 
+0

+1优秀。所有的基地似乎都有很好的解释,做得很好。我希望SO会让更多的选票质量。 – Matt

+0

非常感谢您的帮助和解释@丹!非常感激。 – dede

+0

@Dan如果只有当最大值是MyMatrix的第一列或最后一列时才需要NaN,我该如何更改代码的最后部分?相反,当最大值在第二列时,我想计算考虑最大值之前的一列,最大值和最大值之后的两列的平均值。而当最大值位于倒数第二列时,我想考虑最大值,最大值之前的两列以及最大值之后的一列。 – dede

1

这将需要平均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 

更新:对不起,我已经更新其中存储在最后一列

+1

而不是使'0'的意思是,你可以像这样使用'min'和'max'来忽略那些“离开边缘”元素的意思(MyMatrix(i,max(Ind(i)-2,1 ):min(Ind(i)+ 2,end)))' – Dan

+0

好主意!我将更新我的回答 – Umar

+1

以及那个更新,你不再需要'if'语句;)你也可以用'end + 1'替换你的'endRow'。我认为在这种情况下使用循环是一个很好的解决方案btw,绝对更容易遵循。 – Dan

相关问题