没有重复的行 - MATLAB

时间:2015-02-07 01:45:30

标签: matlab matrix repeat matrix-indexing

我有一个matrix(4096x4),其中包含从8个数字池中取得的四个值的所有可能组合。

...
3    63    39     3
3    63    39    19
3    63    39    23
3    63    39    39
...

我只对包含四个唯一值的矩阵行感兴趣。例如,在上一节中,应删除第一行和最后一行,为我们提供 -

...
3    63    39    19
3    63    39    23
...

我当前的解决方案感觉不够优雅 - 基本上,我遍历每一行并将其添加到result矩阵中,如果它包含四个唯一值:

result = [];
for row = 1:size(matrix,1)
    if length(unique(matrix(row,:)))==4
        result =  cat(1,result,matrix(row,:));
    end
end

有更好的方法吗?

2 个答案:

答案 0 :(得分:3)

方法#1

diff sort 的方法必须非常高效 -

sortedmatrix = sort(matrix,2)
result = matrix(all(diff(sortedmatrix,[],2)~=0,2),:)

将其分解为几个步骤以便解释

  1. 沿着列排序,以便每行中的重复值最终彼此相邻。我们使用sort执行此任务。
  2. 找出连续元素之间的差异,这些元素将在排序后捕获这些重复元素。 diff是用于此目的的工具。
  3. 对于at least one zero的任何行,表示具有重复行的行。换句话说,no zero的任何行都表示没有重复行的行,我们希望在输出中找到这些行。 all让我们完成了这项工作,以获得这种匹配的逻辑数组。
  4. 最后,我们使用matrix indexingmatrix中选择这些行以获得预期的输出。

  5. 方法#2

    这可能是基于实验 bsxfun 的方法,因为它不会有内存效率 -

    matches = bsxfun(@eq,matrix,permute(matrix,[1 3 2]))
    result = matrix(all(all(sum(matches,2)==1,2),3),:)
    

    将其分解为几个步骤以便解释

    1. 使用bsxfun查找每个元素与同一行中所有其他元素的匹配逻辑数组。
    2. 寻找"非双重性"通过在dim-2个匹配项中对这些匹配项求和,然后在all onesdim-2中找到dim-3个元素,使我们获得与之前基于diff + sort的索引数组相同的索引数组方法
    3. 使用二进制索引数组从matrix中选择适当的行作为最终输出。

    4. 方法#3

      从MATLAB文件交换的帖子combinator获取帮助 假设您在名为8的数组中拥有pool8值池,您可以直接获取result -

      result = pool8(combinator(8,4,'p'))
      

      combinator(8,4,'p')基本上为我们提供8元素的索引4一次而不重复。我们使用这些索引来索引pool并获得预期的输出。

答案 1 :(得分:1)

对于有限数量的池,这将起作用。 Create是唯一数组,遍历池中的每个数字,计算它在行中出现的次数,如果找到一个或零个数字,则仅将IsUnique保持为1。接下来,找到IsUnique仍为1的位置,提取这些行并完成。

matrix = [3,63,39,3;3,63,39,19;3,63,39,23;3,63,39,39;3,63,39,39;3,63,39,39];
    IsUnique = ones(size(matrix,1),1);
    pool = [3,63,39,19,23,6,7,8];
    for NumberInPool = 1:8    
        Temp = sum((matrix == pool(NumberInPool))')';
        IsUnique = IsUnique .* (Temp<2);
    end
    UniquePositions = find(IsUnique==1);
    result = matrix(UniquePositions,:)