2015-06-16 110 views
0

我試圖合併兩個在多列中共享相同值的矩陣。在MATLAB的不同向量中加入具有相同值的矩陣

以下矩陣應該舉例說明我的問題並提供MWE。但是,我的數據非常長,因此我正在尋找一種有效的方法來合併它們。數據由選項數據組成,其中c被調用,p輸入數據,1:4列:日期,罷工,到期,出價。最後,我想有矩陣1:5列:日期,罷工,到期,看漲期權價格,投標價格。如MWE中所示,數據長度不同,但列1:3(日期,罷工,到期)的每個組合只存在一次。

c = [7356011 300 7356081 1.15; 7356011 400 7356081 1.56; 7356011 500 7356081 1.79; 7356011 300 7356088 1.25; 7356011 400 7356088 1.67; 7356011 500 7356088 1.89; 7356011 600 7356088 1.92; 7356012 300 7356081 0.79; 7356012 400 7356081 0.99; 7356012 500 7356081 1.08; 7356012 300 7356088 0.81; 7356012 400 7356088 0.90; 7356012 500 7356088 1.07]

p = [7356011 300 7356081 1.35; 7356011 400 7356081 1.15; 7356011 500 7356081 1.03; 7356011 300 7356088 1.56; 7356011 400 7356088 1.15; 7356011 500 7356088 1.03; 7356012 300 7356081 1.25; 7356012 400 7356081 1.19; 7356012 500 7356081 1.02; 7356012 300 7356088 1.14; 7356012 400 7356088 0.98; 7356012 500 7356088 0.76; 7356012 600 7356088 0.56; 7356012 700 7356088 0.44]

我試圖建立對每列的ID,通過使用strcatnum2str,並獲得 'ID(1)= 73560113007356081' 然而,這需要很長的大量的數據。我也嘗試使用uniqueismember找到一個解決方案,但遇到了多列問題。

祝願輸出爲:

7356011 300 7356081 1.15 1.35 7356011 400 7356081 1.56 1.15 7356011 500 7356081 1.79 1.03 7356011 300 7356088 1.25 1.56 7356011 400 7356088 1.67 1.15 7356011 500 7356088 1.89 1.03 7356011 600 7356088 1.92 NaN 7356012 300 7356081 0.79 1.25 7356012 400 7356081 0.99 1.19 7356012 500 7356081 1.08 1.02 7356012 300 7356088 0.81 1.14 7356012 400 7356088 0.90 0.98 7356012 500 7356088 1.07 0.76 7356012 600 7356088 NaN 0.56 7356012 700 7356088 NaN 0.44

感謝所有幫助

+0

爲什麼你想要的矩陣有NaNs? – SamuelNLP

+0

明白了,沒關係。 – SamuelNLP

回答

1

你並不需要使用一個循環,使用intersect代替。

[~,ic,ip] = intersect(c(:, 1:3),p(:, 1:3),'rows'); 
m = [c(ic, :), p(ip,end)]; 

編輯: 如果要包括NaN S其中不相交像上面的海報。

function m = merge(c, p, nc, np) 
    %check for input arg errors 
    if nargin == 3 
     np = nc; 
    elseif nargin ~= 4 
     disp('Please enter either 3 or 4 arguments') 
     m = {}; 
     return 
    end 

    %make sure they are shaped the same 
    nc = reshape(nc, 1, []); 
    np = reshape(np, 1, []); 

    %And have the same number of elements 
    if numel(nc) ~= numel(np) 
     disp('Please ensure arguments 3 and 4 have the same number of elements') 
     m = {}; 
     return 
    end 

    %The columns that aren't being compared 
    NotNC = find(~ismember(1:size(c,2), nc)); 
    NotNP = find(~ismember(1:size(p,2), np)); 

    %Find the matching rows 
    [matches,ic,ip] = intersect(c(:, nc),p(:, np),'rows'); 

    %Put together matching rows with the other data not included in the match 
    m1 = [matches, c(ic, NotNC), p(ip, NotNP)]; 

    %Find rows that did not matched 
    NotIC = find(~ismember(1:size(c,1), ic)); 
    NotIP = find(~ismember(1:size(p,1), ip)); 

    %Put together data not in the matched set 
    m2 = [c(NotIC, nc), c(NotIC, NotNC), nan(length(NotIC), size(NotNP,2))]; 
    m3 = [p(NotIP, np), nan(length(NotIP), size(NotNC,2)), p(NotIP, NotNP)]; 

    %merge all three lists 
    m = [m1; m2; m3]; 

end 
+0

這比Samuel的帖子快得多。 'tic;合併(a,b,1:3); toc', '已用時間爲0.048150秒。' 'tic; 'tic;塞繆爾(a,b); toc' '已用時間爲8.432094秒。' – user1543042

+0

非常感謝!同樣對@SamuelNLP工作也很好,但是由於我更喜歡​​解決數據的數量! – philippe

0

好吧,我不明白,如果p是總是更大,所以我會寫有if的兩個解決方案。

if length(c) > length(p) 
    xx = length(c); 
    newm = [c NaN(xx, 1)]; 
    row = ismember(c, p, 'rows'); 

    newm(row, end) = p(row, end); 
else 
    xx = length(p); 
    newm = [p(:,1:3) NaN(xx, 1) p(:, end)]; 

    row = ismember(p(:,1:3), c(:,1:3), 'rows'); 

    newm(row, 4) = c(row, end); 
end 

UPDATE:

這個代碼適用於您的本例。

[row_p, row_c] = ismember(p(:,1:3), c(:,1:3), 'rows'); 

newm = []; 

for ii = 1:length(row_p) 
    if row_p(ii) == 1 
     newm = [newm; p(ii, 1:3) c(row_c(ii), end) p(ii, end)]; 
    else 
     newm = [newm; p(ii, 1:3) NaN p(ii, end)]; 
    end 
end 

[row_c, row_p] = ismember(c(:,1:3), p(:,1:3), 'rows'); 

for ii = 1:length(row_c) 
    if row_c(ii) == 1 
     newm = [newm; c(ii, 1:3) c(ii, end) p(row_p(ii), end)]; 
    else 
     newm = [newm; c(ii, 1:3) c(ii, end) NaN]; 
    end 
end 

newm = unique(newm, 'rows'); 
+0

有一點小錯誤,現在糾正。 – SamuelNLP

+0

非常感謝。 'if'語句非常好,因爲矩陣'c'和'p'的長度有時會有所不同 但是,如果我在'c'中另外有一行不在'p'中,並且我又怎麼能解決這個問題?反之亦然。我編輯了這個例子來展示我的意思。從現在開始,不可能選擇一個矩陣作爲基礎矩陣,並填充另一個矩陣。在此先感謝 – philippe

+0

您確定'7356012 700 7356088 NaN 0.44'應該是最後一行嗎? – SamuelNLP

相關問題