Remove single elements from a vector
I have a vector M containing single elements and repeats. I want to remove all individual items. Turning something like [1 1 2 3 4 5 4 4 5]
in [1 1 4 5 4 4 5]
.
I thought I would try to get the count of each item and then use the index to remove what I don't need, something like this:
uniq = unique(M);
list = [uniq histc(M,uniq)];
Though I'm stuck here and not sure how to go forward. Can anyone please help?
source to share
You can get the result with the following code:
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))).';
The idea is to add to the second column a'
, then the accumarray
base in the first column (items a
). After that, the items in the first column are found that add up the sum in the second column. Therefore, these elements are repeated once per a
. Finally, removing them from the first column a
.
source to share
Here is a solution using , and 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)=[];
histcounts
was introduced in R2014b. For earlier versions can be used by replacing this line with the following: hist
tmp=tmp(hist(M,tmp)==1);
source to share
Here's a cheaper alternative:
[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);
Assuming the input
a = 1 1 8 8 3 1 4 5 4 6 4 5
sort the list s
and get the index of the sorted listii
s= 1 1 1 3 4 4 4 5 5 6 8 8
we can find the index of the repeated elements and for that we check if the element is equal to the previous element
x =
0 1 1 0 0 1 1 0 1 0 0 1
however, in the x
first elements of each block are omitted, to find it, we can apply [or]
between each element with the previous element
y =
1 1 1 0 1 1 1 1 1 0 1 1
now we have sorted the boolean index of the repeating elements. It should be reordered in its original order. For this we use the index of the sorted items ii
:
z = 1 1 1 1 0 1 1 1 1 0 1 1
finally, use z to extract only duplicate items.
result = 1 1 8 8 1 4 5 4 4 5
Here is the test result in Octave * for the following input:
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.
* Since it histcounts
was not implemented in Octave , so instead histcounts
I used hist
.
You can test it online
source to share
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)) = [];
Then it Y
will be [1 1 4 5 4 4 5]
. It detects all the individual elements and makes them like NaN
and then removes all the elements NaN
from the vector.
source to share