我有一个包含单个元素和重复的向量M.我想删除所有单个元素。将类似[1 1 2 3 4 5 4 4 5]
的内容转换为[1 1 4 5 4 4 5]
。
我以为我会尝试获取每个元素的计数,然后使用索引删除我不需要的内容,如下所示:
uniq = unique(M);
list = [uniq histc(M,uniq)];
虽然我被困在这里并且不确定如何前进。有人可以帮忙吗?
答案 0 :(得分:2)
以下是使用unique
,histcounts
和ismember
的解决方案:
tmp=unique(M) ; %finding unique elements of M
%Now keeping only those elements in tmp which appear only once in M
tmp = tmp(histcounts(M,[tmp tmp(end)])==1); %Thanks to rahnema for his insight on this
[~,ind] = ismember(tmp,M); %finding the indexes of these elements in M
M(ind)=[];
R2014b中引入了 histcounts
。对于早期版本,可以使用hist
替换该行:
tmp=tmp(hist(M,tmp)==1);
答案 1 :(得分:1)
您可以使用以下代码获得结果:
A = [a.', ones(length(a),1)];
[C,~,ic] = unique(A(:,1));
result = [C, accumarray(ic,A(:,2))];
a = A(~ismember(A(:,1),result(result(:,2) == 1))).';
我们的想法是,将{1}添加到a'
的第二列,然后根据第一列accumarray
的元素添加a
。之后,在第一列中找到了第二列中累积和的元素。因此,这些元素在a
中重复一次。最后,将其从A
的第一列中删除。
答案 2 :(得分:1)
这是一个更便宜的选择:
[s ii] = sort(a);
x = [false s(2:end)==s(1:end-1)]
y = [x(2:end)|x(1:end-1) x(end)]
z(ii) = y;
result = a(z);
假设输入是
a =
1 1 8 8 3 1 4 5 4 6 4 5
我们对列表s
进行排序,并获取排序列表ii
s=
1 1 1 3 4 4 4 5 5 6 8 8
我们可以找到重复元素的索引,为此我们检查元素是否等于前一个元素
x =
0 1 1 0 0 1 1 0 1 0 0 1
然而在x
中,每个块的第一个元素被省略以找到它,我们可以在每个元素与前一个元素之间应用[or]
y =
1 1 1 0 1 1 1 1 1 0 1 1
我们现在已经对重复元素的逻辑索引进行了排序。它应按原始顺序重新排序。为此,我们使用已排序元素的索引ii
:
z =
1 1 1 1 0 1 1 1 1 0 1 1
最后使用z来仅提取重复的元素。
result =
1 1 8 8 1 4 5 4 4 5
以下是Octave *测试的结果:
a = randi([1 100000],1,10000000);
-------HIST--------
Elapsed time is 5.38654 seconds.
----ACCUMARRAY------
Elapsed time is 2.62602 seconds.
-------SORT--------
Elapsed time is 1.83391 seconds.
-------LOOP--------
Doesn't complete in 15 seconds.
*由于在Octave histcounts
尚未实施,因此我使用了histcounts
代替hist
。
您可以对其进行测试Online
答案 3 :(得分:0)
X = [1 1 2 3 4 5 4 4 5];
Y = X;
A = unique(X);
for i = 1:length(A)
idx = find(X==A(i));
if length(idx) == 1
Y(idx) = NaN;
end
end
Y(isnan(Y)) = [];
然后,Y
将是[1 1 4 5 4 4 5]
。它会检测所有单个元素,并将它们设为NaN
,然后从向量中删除所有NaN
个元素。