代码之家  ›  专栏  ›  技术社区  ›  shamalaia

基于“表面”值提取三维矩阵的列-矢量化

  •  1
  • shamalaia  · 技术社区  · 6 年前

    我有一个NXMXK矩阵 A

    A = [1 2 1; 1 1 2];
    A = cat(3, A, [3 3 3; 3 3 3])
    

    A(:,:,1)=

     1     2     1
     1     1     2
    

    A(:,:,2)=

     3     3     3
     3     3     3
    

    我想创建一个YXK二维矩阵 B 其中k是 A(:,:,1)==2 :

    k=0;
    for ii=1:size(A,1)
       for jj=1:size(A,2)
          if A(ii,jj)==2
             k=k+1;
             B(k,:) = A(ii,jj,:);
          end
       end
    end
    

    有没有一种向量化此代码的方法?

    我试图找出 A(:,:,1)==2 然后尝试选择整个列,但我不知道如何选择:

    inds = find(A(:,:,1)==2)
    B = A(inds,:) %this line does not make sense
    

    编辑 预分配 帮助:

    inds=find(A(:,:,1)==2);
    B=NaN(numel(inds),size(A,3));
    
    k=0;
    for ii=1:size(A,1)
       for jj=1:size(A,2)
          if A(ii,jj)==2
             k=k+1;
             B(k,:) = squeeze(A(ii,jj,:));
          end
       end
    end
    

    但仍然没有矢量化。

    2 回复  |  直到 6 年前
        1
  •  2
  •   Cris Luengo    6 年前

    你第一次尝试矢量化几乎是正确的。只是不要用 find ,但使用逻辑矩阵进行索引。

    inds = A(:,:,1)==2;
    

    这个 inds 矩阵是二维的,不是三维的,所以我们使用 repmat 要沿第3维度重复其值,请执行以下操作:

    K = size(A,3);
    inds = repmat(inds,1,1,K);  % or simply cat(3,inds,inds) if K==2
    B = A(inds);
    

    结果是大小的列向量 Y*K ,不是大小矩阵 Y X K ,我们可以使用 reshape 要解决这个问题:

    B = reshape(B,[],K);
    

    我想这个答案和 Anthony's ,但索引和重塑是相反的。直到我把相似之处写下来,我才真正注意到。我想安东尼的也有点短。:

        2
  •  3
  •   Anthony    6 年前

    你可以 reshape 矩阵 A 到(n*m)xk二维矩阵。

    A = [1 2 1; 1 1 2];
    A = cat(3, A, [3 3 3; 3 3 3]);
    
    A_ = reshape(A,numel(A(:,:,1)),size(A,3));
    B = A_(A_(:,1)==2,:);