Best way to look for vector within a matrix

1 回表示 (過去 30 日間)
Lorenzo
Lorenzo 2013 年 4 月 30 日
Dear all, I have a matrix M (lot of lines, 7 columns) and a vector v (again lot of lines but not the same ad M and 3 columns) and I need to find the lines of M for which the first 3 columns are equal to the column of a certain line of v.
What I'm currently doing is:
for m=1:length(v)
n=find(M(:,1) == v(m,1) & M(:,2) == v(m,2) & M(:,3) == v(m,3));
if isempty(n)
results(m,1:4)=nan;
else
results(m,1:4)=M(n,4:7);
end
end
Now, since M is quite big and so is v (in terms of line numbers), is there any way to achieve this in a quicker way than what I'm doing?
  1 件のコメント
Jan
Jan 2013 年 4 月 30 日
編集済み: Jan 2013 年 4 月 30 日
Please specify "a lot": It could be 100 or 10 billion, but this obviously matters for a solution.
The values of M and v matter also: If they are integers in the range of [0, 255], combining them to a UNIT32 would allow a simple ISMEMBER call.

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

回答 (3 件)

Jan
Jan 2013 年 4 月 30 日
[Lia, Locb] = ismember(M(:, 3), v, 'rows');
fullb = locb(Locb ~= 0);
result(fullb) = M(Lia, 4:7);
I cannot test this currently. Perhaps the indexing must be changed. But the general method should be clear.

Lorenzo
Lorenzo 2013 年 4 月 30 日
Thank you Jan; sorry for the information I missed. My matrices/vectors have around 550k rows and are made of rationals.
In your answer, what is locb (without capital L)?
Thanks again!
  1 件のコメント
Cedric
Cedric 2013 年 4 月 30 日
編集済み: Cedric 2013 年 4 月 30 日
There are actually two small typos in the first two lines:
[Lia, Locb] = ismember(M(:,1:3), v, 'rows');
fullb = Locb(Locb ~= 0);
If you want to understand, build a simpler test case:
>> M = randi(4, 20, 7)
M =
1 2 4 1 3 3 1
2 4 2 4 1 1 1
2 4 2 3 3 3 1
2 3 1 4 4 4 4
1 3 2 4 1 1 4
2 1 2 2 1 3 2
1 3 1 4 2 4 1
1 3 4 4 4 2 3
1 4 2 2 4 3 4
4 2 4 4 1 2 4
1 4 4 1 1 4 4
4 1 1 1 1 1 4
1 1 3 1 3 3 1
3 1 2 2 2 3 1
3 4 1 2 2 2 2
3 4 2 1 1 4 1
2 1 1 3 1 2 4
4 1 1 4 4 2 2
3 3 3 2 3 3 2
4 2 1 4 3 2 1
>> v = randi(4, 10, 3)
v =
3 2 2
1 2 4
4 1 4
1 3 4
3 4 3
2 2 3
3 4 2
1 4 2
1 4 3
1 1 3
>> [Lia, Locb] = ismember(M(:, 1:3), v, 'rows');
>> [Lia, Locb]
ans =
1 2
0 0
0 0
0 0
0 0
0 0
0 0
1 4
1 8
0 0
0 0
0 0
1 10
0 0
0 0
1 7
0 0
0 0
0 0
0 0
>> class(Lia)
ans =
logical
>> class(Locb)
ans =
double
As you can see, Lia is a vector of logical indices which indicate the location of matches in M (at places where its elements are 1/true). In parallel, Locb is a vector of corresponding locations (given as row numbers) in v. The first element of Lia tells you that row 1 of M(:,1:3) has a match in v, and the first element of Locb tells you that it is row 2 of v.
Now if you want to extract matching rows of M, you can use the vector of logical indices Lia:
>> M(Lia,1:3)
ans =
1 2 4
1 3 4
1 4 2
1 1 3
3 4 2
or
>> M(Lia,:)
ans =
1 2 4 1 3 3 1
1 3 4 4 4 2 3
1 4 2 2 4 3 4
1 1 3 1 3 3 1
3 4 2 1 1 4 1
If you want to extract relevant rows of v, however, you have first to extract non-zero row numbers from Locb, and you can index v with these elements:
>> fullb = Locb(Locb ~= 0)
fullb =
2
4
8
10
7
>> v(fullb,:)
ans =
1 2 4
1 3 4
1 4 2
1 1 3
3 4 2

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


Lorenzo
Lorenzo 2013 年 4 月 30 日
Thank you!

カテゴリ

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

Community Treasure Hunt

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

Start Hunting!

Translated by