Best way to look for vector within a matrix

17 views (last 30 days)
Lorenzo
Lorenzo on 30 Apr 2013
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 Comment
Jan
Jan on 30 Apr 2013
Edited: Jan on 30 Apr 2013
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.

Sign in to comment.

Answers (3)

Jan
Jan on 30 Apr 2013
[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 on 30 Apr 2013
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 Comment
Cedric
Cedric on 30 Apr 2013
Edited: Cedric on 30 Apr 2013
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

Sign in to comment.


Lorenzo
Lorenzo on 30 Apr 2013
Thank you!

Categories

Find more on Creating and Concatenating 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!