Matlab:去除重复值

4

我是一名新手程序员,对MATLAB和编程都比较陌生,我在从矩阵中删除值方面遇到了一些问题。

我有一个包含以下数值的矩阵 tmp2:

tmp2 = [...      ...
        0.6000   20.4000
        0.7000   20.4000
        0.8000   20.4000
        0.9000   20.4000
        1.0000   20.4000
        1.0000   19.1000
        1.1000   19.1000
        1.2000   19.1000
        1.3000   19.1000
        1.4000   19.1000
        ...      ...];

如何删除左列中值为1.0而右列值不同的部分?我想保留19.1这一行。我搜索了一些解决方案,但发现使用histc函数会同时删除两行,这不是我需要的。
谢谢
3个回答

8
您可以使用“unique”来实现此操作:
>> [~,b] = unique(tmp2(:,1)); % indices to unique values in first column of tmp2
>> tmp2(b,:)                  % values at these rows
ans =
    0.6000   20.4000
    0.7000   20.4000
    0.8000   20.4000
    0.9000   20.4000
    1.0000   19.1000
    ...

默认情况下,unique 保存它找到的 最后一个 唯一值,并且输出结果将会被 排序。这恰好是你想要/已经拥有的,所以你很幸运 :)

如果这不是你想要/拥有的,你需要再进行一些修改。保留顺序并移除重复项可以按照以下方式进行:

% mess up the order
A = randperm(size(tmp2,1));
tmp2 = tmp2(A,:)

% use third output of unique
[a,b,c] = unique(tmp2(:,1));

% unique values, order preserved
tmp2(b(c),:)

ans =
    1.1000   19.1000
    1.2000   19.1000
    1.0000   20.4000
    0.7000   20.4000
    1.0000   20.4000
    1.4000   19.1000
    0.6000   20.4000
    0.9000   20.4000
    1.3000   19.1000
    0.8000   20.4000
    ...

该方法仍保留找到的最后一个条目。如果你想保留找到的第一个条目,请使用

% unique values, order preserved, keep first occurrence
[a,b,c] = unique(tmp2(:,1), 'first');

4
我建议在使用unique函数时,设置SetOrder='stable'以保留顺序。 - Dennis Jaheruddin
@DennisJaheruddin:是的,尽管该选项仅适用于新版本的Matlab(不知道从哪个版本开始包括它,但至少不是在R2010a中)。 - Rody Oldenhuis

7

在不使用'rows'选项的情况下使用unique

[C ia ib] = unique( tmp2(:,1) );
C = tmp2( ia, : );

1

我看到了使用unique函数的解决方案,想要提供一个使用循环的解决方案。你可以看一下哪个更快:D!循环可能还可以改进...

clear
tmp = [0.6000   20.4000
        0.7000   20.4000
        0.8000   20.4000
        0.9000   20.4000
        1.0000   20.4000
        1.0000   19.1000
        1.1000   19.1000
        1.2000   19.1000
        1.3000   19.1000
        1.4000   19.1000];

ltmp = length(tmp);
jj = 1;
for ii = 1 : ltmp
    if ii > 1
        if tmp(ii, 1) == tmp(ii - 1, 1)
            continue
        end
    end
    if ii < ltmp
        if tmp(ii, 1) == tmp(ii + 1, 1)
            tmp2(jj,1) = tmp(ii, 1);
            tmp2(jj,2) = min(tmp(ii, 2),tmp(ii + 1, 2));
        else
            tmp2(jj, 1) = tmp(ii, 1);
            tmp2(jj, 2) = tmp(ii, 2);
        end
    else
            tmp2(jj, 1) = tmp(ii, 1);
            tmp2(jj, 2) = tmp(ii, 2);
    end
    jj = jj + 1;
end

5
如果你认为你的循环比 unique 更好:请用小型基准测试展示。否则,只需查看代码告诉我它比 unique 解决方案更好... 此外,在 Matlab 中最好不要将变量名命名为 ij - Shai
2
我认为这个方法“更好”的唯一方式是它总是给出最小值,而不是像unique那样给出第一个或最后一个。它也不会对结果进行排序,但是可以很容易地通过使用unique来实现排序。 - Dennis Jaheruddin

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接