Indexing with intercept for repeating values

1 回表示 (過去 30 日間)
hal9k
hal9k 2021 年 2 月 8 日
コメント済み: the cyclist 2021 年 2 月 22 日
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 件のコメント
Matt J
Matt J 2021 年 2 月 8 日
Couldn't this be a solution,
idx = [0;1;1;1;0;1;1;1;0;0;1;1;1;0];
hal9k
hal9k 2021 年 2 月 18 日
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).

サインインしてコメントする。

採用された回答

Matt J
Matt J 2021 年 2 月 8 日
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 件のコメント
hal9k
hal9k 2021 年 2 月 18 日
Elegant solution but it took really long time for large arrays which I am working with.
Matt J
Matt J 2021 年 2 月 19 日
Well, you didn't say it had to be fast. You just asked for a method that avoided loops.

サインインしてコメントする。

その他の回答 (2 件)

the cyclist
the cyclist 2021 年 2 月 8 日
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 件のコメント
hal9k
hal9k 2021 年 2 月 22 日
編集済み: hal9k 2021 年 2 月 22 日
This works but I wanted to avoid loops.

サインインしてコメントする。


the cyclist
the cyclist 2021 年 2 月 8 日
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 件のコメント
hal9k
hal9k 2021 年 2 月 22 日
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 2021 年 2 月 22 日
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

サインインしてコメントする。

カテゴリ

Help Center および File ExchangeMatrix Indexing についてさらに検索

Community Treasure Hunt

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

Start Hunting!

Translated by