Indexing with intercept for repeating values

1 view (last 30 days)
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 Comments
Matt J
Matt J on 8 Feb 2021
Couldn't this be a solution,
idx = [0;1;1;1;0;1;1;1;0;0;1;1;1;0];
hal9k
hal9k on 18 Feb 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).

Sign in to comment.

Accepted Answer

Matt J
Matt J on 8 Feb 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 Comments
hal9k
hal9k on 18 Feb 2021
Elegant solution but it took really long time for large arrays which I am working with.
Matt J
Matt J on 19 Feb 2021
Well, you didn't say it had to be fast. You just asked for a method that avoided loops.

Sign in to comment.

More Answers (2)

the cyclist
the cyclist on 8 Feb 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 Comment
hal9k
hal9k on 22 Feb 2021
Edited: hal9k on 22 Feb 2021
This works but I wanted to avoid loops.

Sign in to comment.


the cyclist
the cyclist on 8 Feb 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 Comments
hal9k
hal9k on 22 Feb 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 on 22 Feb 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

Sign in to comment.

Categories

Find more on Shifting and Sorting Matrices in Help Center and File Exchange

Community Treasure Hunt

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

Start Hunting!