row indices of an array which is a subset of another array

12 ビュー (過去 30 日間)
Chaitanya Sanghavi
Chaitanya Sanghavi 2017 年 12 月 27 日
コメント済み: Chaitanya Sanghavi 2017 年 12 月 28 日
Eg. b is a matrix of size(17,2). (BIG MATRIX)
b(:,1)= [ 7;6;5;4;4;3;2;1;20;19;18;17;16;20;21;22;23]
b(:,2) = [30;29;28;27;8;9;10;11;8;12;13;14;15;27;26;25;24]
Now, I need the row indices from this array b which has matching entries in a vector a. The size of vector a is smaller than b. But if the indices are repeated, I want the neighboring row entry.
What I mean by neighboring row entry?
lets say a is : [4; 3; 2; 1]. The entries of a will either be in b(:,1) or b(:,2). there would surely not be any intersection. When I search for a in b(:,1) or (b(:,2)), i will get the row indices [5; 6; 7; 8]. (These are the row indices.) When I search for a = [20;21;22;23] in b(:,1), I want it to return the row indices as [14 15 16 17]..
When a is : [7;6;5;4], I want the row indices [1 2 3 4].
"ismember" allows me to return the first or the last row entries. My requirement here is a bit different.

採用された回答

Jan
Jan 2017 年 12 月 27 日
編集済み: Jan 2017 年 12 月 28 日
Maybe your mean:
b = cat(2, [ 7;6;5;4;4;3;2;1;20;19;18;17;16;20;21;22;23], ...
[30;29;28;27;8;9;10;11;8;12;13;14;15;27;26;25;24]);
a = [20; 21; 22; 23];
[~, Result] = ismember(a, b(:, 1), 'legacy');
if ~any(Result)
[~, Result] = ismember(a, b(:, 2), 'legacy');
end
But I detest the 'legacy' flag. Even the documentation is vague about its meaning:
preserves the behavior of the ismember function from R2012b and prior
releases using any of the input arguments in previous syntaxes.
Without knowing what the prior (to what?!) releases did, this description is useless. There is no way to let unique search for 'stable' and 'last' at the same time.
Therefore I'd prefer:
b = cat(2, [ 7;6;5;4;4;3;2;1;20;19;18;17;16;20;21;22;23], ...
[30;29;28;27;8;9;10;11;8;12;13;14;15;27;26;25;24]);
[B1, Index1] = uniqueStableLast(b);
[B2, Index2] = uniqueStableLast(b);
[~, loc] = ismember(a, B1);
if any(loc)
Result = Index1(loc);
else
[~, loc] = ismember(a, B2);
Result = Index2(loc);
end
With:
function [B, AI, BI] = uniqueStableLast(A)
nA = numel(A);
if nA
% Stable with choosing the last element:
[As, SV] = sort(A(:), 'descend');
As = As(nA:-1:1);
SV = SV(nA:-1:1);
% Stable with the first element would be:
% [As, SV] = sort(A(:));
if nargout == 1
UV(SV) = [false; diff(As) ~= 0];
B = A(UV);
else % Indices requested:
UV = [false; diff(As)] ~= 0];
UVs(SV) = UV;
AI = find(UVs);
B = A(UVs);
if nargout == 3
% Complex creation of BI such that BB(BI) == A:
v = zeros(1, nA);
v(AI) = 1:length(AI); % Sequence related to BB
vs = v(SV); % Sorted like A
vf = vs(vs ~= 0); % Just the filled entries
BI(SV) = vf(cumsum(UV)); % Inflate multiple elements
end
end
else
B = [];
AI = [];
BI = [];
end
By the way: This is even faster than Matlab's unique('stable').
  1 件のコメント
Chaitanya Sanghavi
Chaitanya Sanghavi 2017 年 12 月 28 日
Thanks a lot for your effort. !! I am very much concerned for the performance which is nice since you say it works faster than matlab's unique("stable").

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

その他の回答 (0 件)

カテゴリ

Help Center および File ExchangeResizing and Reshaping Matrices についてさらに検索

Community Treasure Hunt

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

Start Hunting!

Translated by