根据列的第一个数字合并数组行

时间:2019-02-25 11:48:41

标签: matlab join merge

我有两个数组,AB。每行的第一位是序列号。

我如何结合AB来拥有一个数组C,以便A中的所有行在B中具有相同的序列号水平连接?

A = [ 12345;
      47542;
      32673;
      65436;
      75343;
      23496;
      54765 ]
B = [ 23566;
      33425;
      65438;
      75354 ]

y = ismember(A(:,1), B(:,1), 'rows');
t=find(y);
C= [A(t,1:12),B(t,1:12)];

我需要C是:

C = [ 12345, 00000;
      23496, 23566;
      32673, 33425;
      47542, 00000;
      54765, 00000;
      65436, 00000;
      75343, 75354]

3 个答案:

答案 0 :(得分:2)

我的方法如下,提取两个数组的前导数字并进行比较:

  a=num2str(A)-'0';
  b=num2str(B)-'0';
  [ida,idb]=ismember(a(:,1),b(:,1));

现在获得A的排序索引

  [~,ids]=sort(a(:,1));

创建输出数组

  C=zeros(size(A,1),2);

最后分配和排序输出

  C(:,1)=A;
  C(ida,2)=B(idb(idb>0));
  %sort result
  C=C(ids,:)

答案 1 :(得分:1)

如果仅是第一位数字,我们只需要检查第一位数字(即floor(A/1e4))是否与09匹配,并相应地进行索引...

% Add some zeros at the front to make indexing work with the unmatched ismember outputs
Az = [zero(; A]; Bz = [0; B];  
% Find the indices for 0 to 9 within the first digits of A and B 
[~,ia] = ismember( 0:9, floor( A/1e4 ) );
[~,ib] = ismember( 0:9, floor( B/1e4 ) );
% Assign to C and discard unmatched rows
C = [Az(ia+1), Bz(ib+1)];
C( all( C==0, 2 ), : ) = [];

请注意,使用floor操作使数字保持数字化总是比在诸如num2str等数字和字符数据之间切换更可取。


修改

您通过注释新数据来更改问题的范围。这是相同的方法,写得更通用,因此可以处理具有更多列和不同幅度ID的AB

% Add some zeros at the front to make indexing work with the unmatched ismember outputs
Az = [zeros(1,size(A,2)); A]; Bz = [zeros(1,size(A,2)); B]; 
% Function for getting first digit
f = @(x) floor(x./(10.^floor(log10(x))));
% Find the indices for 0 to 9 within the first digits of A and B 
[~,ia] = ismember( 0:9, f(A(:,1)) );
[~,ib] = ismember( 0:9, f(B(:,1)) );
% Assign to C and discard unmatched rows
C = [Az(ia+1,:), Bz(ib+1,:)];
C( all( C==0, 2 ), : ) = [];

答案 2 :(得分:0)

首先,整个脚本。乍一看,我不使用循环便找不到解决方案。

A = [ 12345;
      47542;
      32673;
      65436;
      75343;
      23496;
      54765; ]

B = [ 23566;
      33425;
      65438;
      75354; ]

A = sort(A);                              % Sort A and B.
B = sort(B);                             

A_str = int2str(A);                       % Convert integers to chars.
B_str = int2str(B);

A_sn = A_str(:, 1);                       % Extract first columns.
B_sn = B_str(:, 1);                       % Basically, these are the serial numbers.                                              

C = zeros(size(A, 1), size(A, 2) * 2);    % Initialize C.

C(:, 1) = A;                              % First column of C is just A.

for i = 1:length(A_sn)                    % For all serial numbers in A...
  for j = 1:length(B_sn)                  % For all serial numbers in B...
    if (A_sn(i) == B_sn(j))               % Check if serial number in B equals the serial number in A.
      C(i, 2) = B(j);                     % If so, set i-th row in C to the corresponding value in B.
    end
  end
end

C

结果:

A =
    12345
    47542
    32673
    65436
    75343
    23496
    54765

B =
    23566
    33425
    65438
    75354

C =
    12345       0
    23496   23566
    32673   33425
    47542       0
    54765       0
    65436   65438
    75343   75354