提取某些子列的矩阵操作:逆向思想

Matrix manipulation to extract certain sub columns: reverse idea

我有一个矩阵 M 和一个单元格 X,如下所示。 A 包含 M(1:3,:) 的唯一列向量。 A介绍只是为了说明我要的,这不是初始数据。

我尝试修改下面的程序,而不是找到 A(1:3,:) 的列向量,其在 M(4,:) 中的对应值不属于单元格 [=16= 的向量之一](显然不等于这些向量之一)。现在,我想找到 A(1:3,:) 的列向量,其在 M(4,:) 中的对应值至少包含单元格 X 的一个向量(或等于这些向量之一)。 例如,结果应该是:

out =

        622   1007
        124    552
         88   2010

我要修改的代码:

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

A = [1007  4044  5002  622;
      552   300   431  124;
     2010  1113  1100   88];

A 包含 M(1:3,:)

的唯一列向量
 X = {[2 5 68 44],[2 10 55 9 17],[1 55 6 7 8 9],[32 12],[30 12 15]};

[C,~, subs] = unique(M(1:3,:)','rows');

A4 = accumarray(subs(:),M(4,:).',[],@(x) {x});

idxC = true(size(A4));
NX = numel(X);
for ii = 1:length(A4)
    for jj = 1:NX
        xj = X{jj};
        issubset = true;
        for A4i=A4{ii}.'
            if ~ismember(A4i, xj)
                issubset = false;
                break;
            end;
        end;
        if issubset
            idxC(ii) = false;
            break;
        end;
    end;
end;


out = C(idxC,:).';

有两个快捷方式。第一,如果 A4{ii} 的任何元素在 X{jj} 中没有找到,则不要测试 A4{ii} 的剩余部分,从下一个 jj 开始。其次,如果 A4{ii} 的所有元素都在任何 X{jj} 中找到,请不要测试 jj 的剩余值,已经删除 A4{ii}

>> out

out =

    1007        4044
     552         300
    2010        1113

我试过这段代码,它给出了正确的结果,但我不知道它是否正确:

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


 X = {[2 5 68 44],[2 10 55 9 17],[1 55 6 7 8 9],[32 12],[30 12 15]};



[C,~, subs] = unique(M(1:3,:)','rows');

A4 = accumarray(subs(:),M(4,:).',[],@(x) {x});


idxC = false(size(A4));
NX = numel(X);

for jj = 1:NX
     for ii = 1:length(A4)
        A4i=A4{ii};

        issubset = false;
        for xj = X{jj}.'
            if ismember(xj,A4i)
               issubset = true;
               break;
            end;
        end;
        if issubset
            idxC(ii) = true;
            break;
        end;
    end;
end;


out = C(idxC,:).';

out =

         622        1007
         124         552
          88        2010

这是我的方法。在阅读之前,请记住这可能不是 fastest/trickiest 的方式。

%Extracting the values of M(4,:) as blocks (I kept your way to do it)
[C, ~, subs] = unique(M(1:3,:)','rows');    
A4 = accumarray(subs(:),M(4,:).',[],@(x) {x});

%Finding which A4 elements contains at least a vector of x
containsX = arrayfun(@(it)cellfun(@(x)all(ismember(x,A4{it})),X),1:length(A4),'UniformOutput',0)';

%Converting containsX into array so I can use `any`
containsX_array = cell2mat(containsX);

%Extracting the elements of A concerned
out = A(:,find(ismember(A',C(any(containsX_array,2),1:3),'rows')));

我在一些例子中运行做了它,它似乎没有问题。

%TEST :

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

A = [1007  4044  5002  622;
      552   300   431  124;
     2010  1113  1100   88];

X = {[2 5 68 44],[2 10 55 9 17],[1 55 6 7 8 9],[32 12],[30 12 15]};

>> out

out =

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


 X = {[2 5 68 44],[2 10 55 9 17],[1 55 6 7 8 9],[32 12],[30 12 15]};



[C,~, subs] = unique(M(1:3,:)','rows');

A4 = accumarray(subs(:),M(4,:).',[],@(x) {x});


idxC = false(size(A4));
NX = numel(X);

for jj = 1:NX
     for ii = 1:length(A4)
        A4i=A4{ii};

        issubset = false;
        for xj = X{jj}.'
            if ismember(xj,A4i)
               issubset = true;
               break;
            end;
        end;
        if issubset
            idxC(ii) = true;
            break;
        end;
    end;
end;


out = C(idxC,:).';

out =

         622        1007
         124         552
          88        2010