2016-06-08 100 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

相關問題