2015-07-10 51 views
1

的另一個替代方案此目標問題:我正在尋找「X = X1(abs(N(4,:) - N(5,:))> 0.24 * abs(N(5,:)))」

我正在尋找一個代碼,不考慮矩陣NM的列順序。所以,我試圖取代在下面的代碼下面一行:

X = X1(abs(N(4,:)-N(5,:))>0.24*abs(N(5,:))); 

結果X依賴的N列順序和M

問題:

我的目標是如果abs(N(4,i)-N(5,i)) > 0.24*abs(N(5,i))

將與 N(1:3,i), i=1,2,3,4,5對應的 M(4,:)的所有值放入一個單元的一個向量中 X用於查找 X

實體

N(1:3,:)是由M(1:3,:)

N(4:5,:)獨特列向量形成被添加到顯示M否則。

M = [1007 4044 1007 4044 1007 5002 5002 5002 622 622 1007 1007 1007; 
     552 300 552 300 552 431 431 431 124 124 552 11 11; 
    2010 1113 2010 1113 2010 1100 1100 1100 88 88 2010 20 20; 
     12 25 15 12 30  2 10 55 32 12  7 12  7]; 


A = [1007 4044 5002 622 1007 
     552 300 431 124 11 
    2010 1113 1100 88 20 
     12 25  2 32 12 
     15 12 10 12  7 
     30   55 
     7      ] 

N = [622 1007 1007 4044 5002; 
     124 11 552 300 431; 
     88 20 2010 1113 1100; 
     2  4 -1.1 2.1 -3; 
    2.01  1 -1  2 -5]; 

[~,~,idx] = unique(M(1:3,:)','rows','stable') 


%// Accumulate elements from the fourth row of M based on the IDs 
X1 = accumarray(idx(:),M(4,:).',[],@(x) {x}); 

%// Use mask corresponding to abs(N(4,i)-N(5,i))>0.24*N(5,i) and 
%// filter out some of the cells from the output 
X = X1(abs(N(4,:)-N(5,:))>0.24*abs(N(5,:))); 

在我的例子: 如果NM正確下令:

X = {[12,7],[2 10 55]} 

[12 7]對應N(1:3,2)abs(N(4,2)-N(5,2))>0.24*abs(N(5,2))

[2 10 55]對應N(1:3,5)abs(N(4,5)-N(5,5))>0.24*abs(N(5,5))

可能的解決方案:(給我的真實數據正確的結果)

for i = 1:size(N,2) 
    N(6,i) = i; 
end 


for h = 1:size(M,2) 
    for l = 1:size(N,2) 
     if M(1:3,h) == N(1:3,l) 
      M(5,h) = N(6,l); 
     end 
    end 
end 

p = 0; 
for i = 1:size(N,2) 
    if abs(N(4,i)-N(5,i))>0.24*abs(N(5,i)) 
     Mint = M(:,ismember(M(5,:).',i.', 'rows').'); 
     p = p+1; 
     X{1,p} = Mint(4,:); 
    end 
end 
+0

你想創建的M爲N的解決方案,然後進行分析,無論M的:此代碼你對你發佈的數據集越大匹配的解決方案?或者你是否想要一個解決方案,將N和M給出,因爲它似乎對於你提出的顯式問題有解決方案,是否要求可以從任何矩陣M執行此操作的操作,而不管M中值的位置如何N + – bern

+0

@bern:N和M是問題的初始數據。並且該解決方案應適用於任何矩陣M,而不管M或N中的值的位置如何。 – bzak

回答

1

ismember是一個很好的解決您的問題。它告訴你什麼時候一個矩陣的元素(或行)出現在第二個矩陣中,並且比使用循環的方法快得多。

isGood = abs(N(4,:)-N(5,:))>0.24*abs(N(5,:)); 

[junk, inds] = ismember(M(1:3, :)', N(1:3, isGood)', 'rows'); 

X = cell(1, sum(isGood)); 
for i = 1:sum(isGood) 
    X{i} = M(4, inds==i); 
end 
1

看看這對你的作品 -

%// Inputs 
M = [1007 4044 1007 4044 1007 5002 5002 5002 622 622 1007 1007 1007; 
     552 300 552 300 552 431 431 431 124 124 552 11 11; 
    2010 1113 2010 1113 2010 1100 1100 1100 88 88 2010 20 20; 
     12 25 15 12 30  2 10 55 32 12  7 12  7]; 

N = [622 1077 1007 4044 5002; 
     124 11 552 300 431; 
     88 20 2010 1113 1100; 
     2  4 -1.1 2.1 -3; 
    2.01  1 -1  2 -5]; 

[unqrows,~,idx] = unique(M(1:3,:)','rows','stable') 
unqcols = unqrows.'; 

%// Accumulate elements from the fourth row of M based on the IDs 
X1 = accumarray(idx(:),M(4,:).',[],@(x) {x}); %//' 

%// "Regularize" X1 %//' 
[~,sort_idx] = sortrows(unqcols.'); %//' 
X1_sorted = X1(sort_idx); 

%// Use mask corresponding to abs(N(4,i)-N(5,i))>0.24*N(5,i) and 
%// filter out some of the cells from the output 
X = X1_sorted(abs(N(4,:)-N(5,:))>0.24*abs(N(5,:))); 

%// Sort, keep unique elements and make them row vectors 
%// within each cell of X (if needed) 
X = cellfun(@(x) unique(x).',X,'Uni',0); 

輸出 -

>> celldisp(X) 
X{1} = 
    7 12 
X{2} = 
    2 10 55 
+0

始終存在相同的問題!我在我的問題中添加了一個解決方案,與您對另一個問題的答案相關聯,可以爲我的真實數據提供正確的結果。 – bzak

+0

@bzak您可能的解決方案不適用於問題中列出的玩具示例,對不對?它的輸出似乎不符合那裏的預期輸出。 – Divakar

+0

是的,你是對的:( – bzak

1

使用邏輯索引將大大加快你的劇本。 MATLAB for循環並不是很好。試試以下代碼:

k = size(N,2); 
r = size(M,2); 
M(5:7,:) = 0; 

for ii = 1:k 
    index = sum(M(1:3,:) == repmat(N(1:3,ii),1,r),1)>2; 
    M(5,index) = ii; 
    M(6,index) = N(4,ii); 
    M(7,index) = N(5,ii); 
end 

filter = abs(M(6,:)-M(7,:))>0.24*abs(M(7,:)); 

X = {}; 
for ii = 1:k 
    X = [X, M(4,M(5,:) == ii& filter)]; 
end 

在我的電腦上,執行您的代碼需要0.017825秒。礦耗了0.002780秒。我會說這是一些改進。如果您想進行更詳細的比較,請使用profile

+0

感謝您的回答。但通過我的真實數據,我發現你的代碼和我的「可能的解決方案」有兩個不同的結果! – bzak

+0

您是否介意發佈一些會導致您的可能解決方案與我的不同結果的數據?我的意思是我的代碼與您的代碼工作原理相同。我只是使用'repmat'來擴展你需要從'N'作爲選擇標準並追加到M中,這樣它可以運行得更快。 – user3667217

+0

https://www.dropbox.com/s/0fjf0zjw74wrzc7/matrice_test_1.mat?dl=0 – bzak