2015-06-16 49 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

相关问题