Best way to look for vector within a matrix

11 次查看(过去 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 CenterFile Exchange 中查找有关 Creating and Concatenating Matrices 的更多信息

Community Treasure Hunt

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

Start Hunting!

Translated by