【问题标题】:Find permutations of rows in matrix查找矩阵中行的排列
【发布时间】:2013-05-26 09:50:15
【问题描述】:

我正在编写一段代码,它应该在 Nx3 矩阵 E 中找到包含 Mx3 矩阵 T 的值的行,但它们的顺序不一定相同。我写了一些有效的东西,但我对这种风格不满意,并希望使用ismember 对矩阵应用逻辑运算并找到,而不是我正在使用的循环:

E = [7 36 37; 9 1 5; 4 34 100; 4 12 33; 4 34 33];
T = [37 7 36; 4 34 33];      

for i=1:size(T,1)
    T(i,:) = sort(T(i,:));
end

for i=1:size(E,1)
    E(i,:) = sort(E(i,:));
end

res = zeros(size(T,1),1);
for i=1:size(T,1)
    a = ismember(E,t(i,:));    
    res(i,1) = find(sum(a,2)==3);
end

我的想法是对ET 的每一行进行排序,这样它们的顺序就会相同,然后用循环比较每一行。但是,我正在尝试学习以更 MATLAB 风格编写我的代码,并希望应用 ismember 并可能会找到执行相同的操作。像这样的:

a = sum(ismember(E,T(1,1))~=0,2);
b = sum(ismember(E,T(1,2))~=0,2);
c = sum(ismember(E,T(1,3))~=0,2);
r = find(a&b&c);

还有更优雅的解决方案吗?

谢谢!

【问题讨论】:

  • 您考虑过ismember(A,B,'rows') 还是setdiff?任何基于排序的解决方案都可能会有点混淆,即使它是高性能的。

标签: matlab matrix


【解决方案1】:

您可以将ismember'rows' 选项一起使用:

ismember(sort(E, 2), sort(T, 2), 'rows')

这会产生一个逻辑(布尔)向量,指示矩阵T 的哪些行(或它们的任何排列)出现在矩阵E 中。请注意,每一行都独立排序以处理重新排序。

如果您需要T 行的索引,请使用ismember 的两个输出:

[tf, loc] = ismember(sort(E, 2), sort(T, 2), 'rows')

注意:如果您的数据包含浮点数,ismember 方法可能会失败,因此您需要设置一个容差进行比较。请参阅this answer 以了解更强大的替代方法(并记住首先沿 2nd 维度对输入矩阵进行排序!)。

示例

E = [7 36 37; 9 1 5; 4 34 100; 4 12 33; 4 34 33];
T = [37 7 36; 4 34 33];
[tf, loc] = ismember(sort(E, 2), sort(T, 2), 'rows');

结果是:

tf =          loc =
     1              1
     0              0
     0              0
     0              0
     1              2

【讨论】:

  • 再次感谢艾坦!这是我一直在寻找的解决方案。但是,它会跳过 3 个值(仅在 T 的 75 个索引中找到 72 个)。一分钟后会调查。
  • 矩阵是双精度类型,但值(显示)为整数。
  • @TheodorBecker 如果您的矩阵只包含纯整数,那么ismember 应该不会有任何问题。检查您的数据。
【解决方案2】:

您可以使用bsxfuneq 函数执行您的要求:

Esorted = sort(E, 2);
Tsorted = sort(T, 2);

rowsEq = bsxfun(@eq, Esorted, permute(Tsorted, [3 2 1]));
rowsEqInd = sum(rowsEq, 2) == size(T, 2);
EEqInd = sum(rowsEqInd, 3) > 0;

无需在循环中对 ET 的每一行进行排序 - sort 将为您完成此操作。 rowsEq 是一个 3-D 数组,表示 T 的每一行中的元素与 E 的每一行中的元素相等;其中1s在这个矩阵的一行中,ET的行是相等的,所以我们总结并测试1s的个数是3(或size(T, 2)) .我们留下了一个数组,分别表示 T 的每一行的相等性,所以最后的 sum 将这些结果结合起来给出你想要的。

【讨论】:

  • 谢谢 wakjah,我试过了,但由于某种原因它只在 EEQInd 中返回 0。另外,在这种情况下,我更喜欢 Eitan 的解决方案!
猜你喜欢
  • 1970-01-01
  • 2017-08-11
  • 1970-01-01
  • 1970-01-01
  • 2014-06-02
  • 2019-08-11
  • 1970-01-01
  • 2013-04-20
  • 1970-01-01
相关资源
最近更新 更多