Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/matlab/16.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
MATLAB-查找数组中的重复项并对其编号_Matlab_Unique - Fatal编程技术网

MATLAB-查找数组中的重复项并对其编号

MATLAB-查找数组中的重复项并对其编号,matlab,unique,Matlab,Unique,我有一个值数组,其中一些值有重复项,例如: a = [5;5;4;7;7;3;3;9;5;7] b = [1;1;0;2;2;3;3;0;1;2] 我想找出哪些是重复的,然后按顺序对每个进行编号,同时使不重复的为零。例如: a = [5;5;4;7;7;3;3;9;5;7] b = [1;1;0;2;2;3;3;0;1;2] 目前我有一个非常低效且不完整的方法,使用unique函数和各种for循环和if语句,但我觉得应该有一个简单的答案 获得此答案的最有效方法是什么?您可以结合使用和进行

我有一个值数组,其中一些值有重复项,例如:

a = [5;5;4;7;7;3;3;9;5;7]
b = [1;1;0;2;2;3;3;0;1;2]
我想找出哪些是重复的,然后按顺序对每个进行编号,同时使不重复的为零。例如:

a = [5;5;4;7;7;3;3;9;5;7]
b = [1;1;0;2;2;3;3;0;1;2]
目前我有一个非常低效且不完整的方法,使用
unique
函数和各种
for
循环和
if
语句,但我觉得应该有一个简单的答案


获得此答案的最有效方法是什么?

您可以结合使用和进行必要的调整:

a = [5;5;4;7;7;3;3;9];

% Identify unique values and their counts
[uniquevals, ~, ia] = unique(a, 'stable');  % Stable keeps it in the same order
bincounts = accumarray(ia, 1);  % Count the frequency of each index in ia

% Zero out singles
singles = uniquevals(bincounts <= 1);
[~, singleidx] = intersect(a, singles);
a(singleidx) = 0;

% Overwrite repeats
repeats = uniquevals(bincounts > 1);
[~, a] = ismember(a, repeats);

演练 我们在这里使用
unique
查找输入数组
a
中的所有唯一值。我们还存储可选的第三个输出,这是
a
的值到它们在唯一值数组中的索引的映射。请注意,我们正在使用
stable
选项,以在
a
中首次遇到的顺序获取唯一值;默认情况下,
unique
的结果进行排序


然后,我们使用
accumarray
来累加从
unique
获得的下标,这将为我们提供每个索引的计数。使用,我们首先使用这些计数将单个实例归零。将这些值归零后,我们可以使用
ismember
的第二个输出返回最终答案

这是一个基于索引、逻辑运算符和:

编辑:

编辑问题时,要处理非连续重复项,可以执行以下操作:

[s ii] = sort(a);
x = [false ;s(2:end)==s(1:end-1)];
y = [x(2:end)|x(1:end-1) ;x(end)];
first = ~x&y;
[~,ix]=sort(ii(first));
un(ix,1)=1:numel(ix);
result(ii,1)=un(cumsum(first)).*y;

这是一个两行程序,也适用于非连续副本

[c, ia, ic] = unique(a, 'stable');
[~, b] = ismember(a, a(ia(accumarray(ic,1)>1)));

我使用了一些修改后的想法。

这里是另一种方法:

a = [5;5;4;7;7;3;3;9;5;7];
[u, ~, w] = unique(a, 'stable');
s = find(sum(bsxfun(@eq, a, u.'), 1) > 1);
b = sum(bsxfun(@times, bsxfun(@eq, w, s), 1:numel(s)), 2);
在R2016b之后的版本中,您可以简化语法:

a = [5;5;4;7;7;3;3;9;5;7];
[u, ~, w] = unique(a, 'stable');
s = find(sum(a==u.', 1) > 1);
b = sum((w==s).*(1:numel(s)), 2);

类似于
[5;5;4;7;7;3;3;9;5;5;4;7]
的输入是否可能?结果会怎样?@LuisMendo是的,这种输入也是可能的。我已经修改了这个问题,将非连续重复的问题包括在内。我喜欢这种有效的方法。这只会找到连续的副本。@Y.change谢谢!除了我收到一个新的反馈之外,OP似乎想要连续的重复。不能确切地说问题出在哪里,但是如果存在两个以上相同的元素,你的第二种方法就会出错。例如,对于
a=[5;5;5;4;7;7;3;3;3;3;9]。还是很整洁很难。@LeanderMoesinger谢谢,你是对的,第二种方法被删除了。