【问题标题】:Matrix manipulation to extract certain sub columns矩阵操作以提取某些子列
【发布时间】:2015-05-22 08:33:10
【问题描述】:
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]}

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

A 是一个解释我想要什么的实体。

A 包含M(1:3,:) 的唯一列向量,以及M(4,:) 中的对应值

A(1:3,:) = unique(M(1:3,:)','rows')'

我希望找到A(1:3,:) 的列向量,其在M(4,:) 中的对应值不属于单元格X 的向量之一(并且显然不等于这些向量之一)。

对于我的示例,所需的结果是矩阵:

 [1007  4044; 
   552   300; 
  2010  1113;]

列向量[5002;431;1100] 被删除,因为[2;10;55] 包含在X{2} = [2 10 55 9 17]

列向量[622;124;88] 被消除,因为[32 12] = X{4}

【问题讨论】:

  • 你尝试过使用循环吗?
  • @Dan:我在寻找没有循环的解决方案,因为我的矩阵的大小大于 1000000 !!
  • 从循环开始并首先做好。然后如果它太慢,在这里发布你的代码,也许有人可以帮助优化它。但就目前而言,您只是要求提供代码,而没有表明您已尝试自己解决问题。
  • 如果你真的想在没有循环的情况下尝试它(但我强烈建议你先从循环开始),那么我会考虑使用accumarray 来构建你的其余部分A 矩阵(不包括前三行,并将其保留为单独的矩阵),您可能会发现 unique 语句中的其他输出有助于生成 accumarray 所需的输入

标签: matlab matrix cell-array


【解决方案1】:

输入:

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]};

这样做(你做了什么)

A(1:3,:) = unique(M(1:3,:).','rows').';

给予:

>> A

A =

     622        1007        4044        5002
     124         552         300         431
      88        2010        1113        1100

然后使用uniqueaccumarray

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

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

现在我们将A4 作为单元阵列

>> A4

A4 = 

[2x1 double]    [4x1 double]    [2x1 double]    [3x1 double]

然后使用cellfunismemberallany

%// getting a mask of which columns we want
idxC(length(A4)) = false;
for ii = 1:length(A4)
    idxC(ii) = ~any(cellfun(@(x) all(ismember(A4{ii},x)), X));
end

显示我们想要的列

out = A(:,idxC)

结果:

>> out

out =

    1007        4044
     552         300
    2010        1113

我建议您按照@Dan 的建议自己尝试一下。如果你被困在某个地方,你可以参考这个。如果您有任何澄清/修改,请告诉我:)

【讨论】:

  • 有一个问题,我认为循环应该在 A 而不是 X 的长度上!因为当我在我的数据上应用代码时,我得到:???索引超出矩阵维度。 ==> @(x)all(ismember(A4{ii},x)) 中的错误 ==> idxC(ii) = ~any(cellfun(@(x) all(ismember(A4{ii},x) )), X));但即使在那种情况下,我也会遇到同样的错误
  • @bzak,感谢您指出.. 已编辑.. 即使使用length(A4),您是否遇到错误?你能上传你正在使用的实际数据吗?
  • 我想我找到了问题所在,在我的矩阵 M 中,第一行的多个值被重复,但不属于 A(1:3,:) 的同一个向量。所以在代码中,我们应该考虑: [~, ~, subs] = unique(M(1:3,:)','rows');而不是: [~, ~, subs] = unique(M(1,:));
  • 是的,它可以工作,但每次迭代之间的计算时间为 2 秒。所以如果length(A4) = 20000,计算时间就是20000*2s!!!
  • 为什么避免循环困难?
猜你喜欢
  • 2018-06-28
  • 1970-01-01
  • 2021-12-16
  • 1970-01-01
  • 1970-01-01
  • 2021-10-14
  • 1970-01-01
相关资源
最近更新 更多