Indexing with intercept for repeating values

1 vue (au cours des 30 derniers jours)
hal9k
hal9k le 8 Fév 2021
Commenté : the cyclist le 22 Fév 2021
a = [1;1;1;2;3;3;4;5;6;7];
b = [1;1;1;1;1;2;3;4;4;4;5;6;7;7];
% I should get the following logical index as answer. Find position in b with equivalent in a.
idx = [1;1;1;0;0;1;1;1;0;0;1;1;1;0];
I tried intersect and ismember but cant seem to find an elegant way without looping. Thanks in advance!
  4 commentaires
Matt J
Matt J le 8 Fév 2021
Couldn't this be a solution,
idx = [0;1;1;1;0;1;1;1;0;0;1;1;1;0];
hal9k
hal9k le 18 Fév 2021
Sorry no! The idx should have first 3 values set as 1,1,1 and 4th value is 0 (since there is no other 1's left in a).

Connectez-vous pour commenter.

Réponse acceptée

Matt J
Matt J le 8 Fév 2021
a = [1;1;1;2;3;3;4;5;6;7];
b = [1;1;1;1;1;2;3;4;4;4;5;6;7;7];
c = splitapply(@(x){(1:numel(x)).'<=sum(a==x(1))} , b , findgroups(b));
idx=cell2mat(c)
idx = 14x1 logical array
1 1 1 0 0 1 1 1 0 0
  5 commentaires
hal9k
hal9k le 18 Fév 2021
Elegant solution but it took really long time for large arrays which I am working with.
Matt J
Matt J le 19 Fév 2021
Well, you didn't say it had to be fast. You just asked for a method that avoided loops.

Connectez-vous pour commenter.

Plus de réponses (2)

the cyclist
the cyclist le 8 Fév 2021
Here is one way:
a = [1;1;1;2;3;3;4;5;6;7];
b = [1;1;1;1;1;2;3;4;4;4;5;6;7;7];
idx = zeros(numel(b),1);
ii = 1;
while any(b) && any(a)
if a(1)==b(1)
idx(ii) = 1;
a(1) = [];
b(1) = [];
ii = ii+1;
elseif b(1) < a(1)
b(1) = [];
ii = ii+1;
else
a(1) = [];
end
end
idx
idx = 14×1
1 1 1 0 0 1 1 1 0 0
This method "cannibalizes" a and b, so you should make copies of those first if you need them.
  1 commentaire
hal9k
hal9k le 22 Fév 2021
Modifié(e) : hal9k le 22 Fév 2021
This works but I wanted to avoid loops.

Connectez-vous pour commenter.


the cyclist
the cyclist le 8 Fév 2021
Here is one way:
a = [1;1;1;2;3;3;4;5;6;7];
b = [1;1;1;1;1;2;3;4;4;4;5;6;7;7];
ha = histcounts(a,1:max(a)+1);
hb = histcounts(b,1:max(b)+1);
d = max(0,min(hb,ha));
idx = zeros(numel(b),1);
loc = cumsum([1,hb]);
for ii = 1:numel(d)
idx(loc(ii):loc(ii)+d(ii)-1) = 1;
end
idx
idx = 14×1
1 1 1 0 0 1 1 1 0 0
  2 commentaires
hal9k
hal9k le 22 Fév 2021
I tested this but it would fail for this:
a = [1;1;1;2;3;3;4;5;6;7];
b = [1;1;1;1;1;2;3;4;4;4;5;6;7;7;8;8]; (a might not have all the elements(
Correct result is idx = [1;1;1;0;0;1;1;1;0;0;1;1;1;0;0;0];
But I got error with the code. So the above code would only work if a and b has same number of unique elements.
the cyclist
the cyclist le 22 Fév 2021
This had a very simple fix.
a = [1;1;1;2;3;3;4;5;6;7];
b = [1;1;1;1;1;2;3;4;4;4;5;6;7;7;8;8];
maxval = max([a;b]);
ha = histcounts(a,1:maxval+1);
hb = histcounts(b,1:maxval+1);
d = max(0,min(hb,ha));
idx = zeros(numel(b),1);
loc = cumsum([1,hb]);
for ii = 1:numel(d)
idx(loc(ii):loc(ii)+d(ii)-1) = 1;
end
idx
idx = 16×1
1 1 1 0 0 1 1 1 0 0

Connectez-vous pour commenter.

Catégories

En savoir plus sur Matrix Indexing dans Help Center et File Exchange

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by