如何获得unique()的二进制输出?

时间:2018-12-31 16:45:58

标签: matlab

[uniq_elements,uniq_indices]=unique(x)

在例如向量x

什么是简单(即单线)和高效(即快速执行时间)的方法,以简单地仅指示“此值是否唯一”,如果没有,则输出重复序列中的第一个?有没有办法使用逻辑运算符来解决这个问题?简单地让函数输出“此值是否唯一”可能是一个开始。

示例代码:

x=[5 5 2 2 3 4 4 1 1 1]; %example values
[~,uniq_indices]=unique(x); %returns [1,3,5,6,8]
result=false(size(x));
result(uniq_indices)=1
%console ouput:
result =

  1×10 logical array

   1   0   1   0   1   1   0   1   0   0

我的基本假设是-由于仅需要逻辑输出-可以更快/更轻松地实现上述代码。

1 个答案:

答案 0 :(得分:4)

方法1

这会占用大量内存,因为它会创建一个中间n×n逻辑矩阵,其中nx的大小:

result = sum(triu(bsxfun(@eq, x, x.')))==1;

自R2016b起,它可以更简洁地表示为

result = sum(triu(x==x.'))==1;

工作原理

bsxfun(@eq, x, x.')(或x==x.')创建相等比较的方阵。

triu仅保留上三角部分,因此每个元素仅与先前的元素或自身进行比较。

sum给出每一列的总和。如果总和为1,则表示该元素不等于任何先前的元素,仅等于自身。

方法2

这稍微提高了内存效率。它创建一个中间m×n逻辑矩阵,其中m是唯一元素的数量,n是元素的总数:

xu = unique(x);
result = any(diff([false(numel(xu),1) bsxfun(@eq, x, xu.')],[],2)==1);

从R2016b开始,第二行可以替换为

result = any(diff([false(numel(xu),1) x==xu.'],[],2)==1);

工作原理

这将创建一个矩阵,例如A,用于比较x的每个唯一元素(A的行索引)与x的每个元素( A)。让B表示向false附加A列的结果。

首次出现在x中的元素对应于[0 1]的相应行中的B子序列。为了检测到这一点,将diff应用于每一行,并将结果与​​1(这是[0 1]中元素之间的增量)进行比较。