Info

This question is closed. Reopen it to edit or answer.

finding values in a Matrix from a list

2 views (last 30 days)
Jens Mischnick
Jens Mischnick on 21 Jul 2014
Closed: MATLAB Answer Bot on 20 Aug 2021
Hey everybody,
I have a vector of numbers, call it 'A', which can repeat, and a much smaller vector of a subset of these numbers,call it 'B'. 'B' may contain values not present in 'A'.
Now I am trying to get the indices in vector 'A' for each value in vector 'B'. After that I want to use some Data,which is stored in another Coloumn of A to perform some analysis,like min, max or mean an store it in Coloumns of B.
For Example:
A = [1 1 2 2 3 3 4 4 5 5 6 6 7 7 8 8 9 9 10 10;...
0 1 1 2 2 3 4 3 5 4 6 7 4 3 2 1 4 5 3 5]'
B = [1 4 6 6.5 8]'
Is there a fast way to do this, preferably without loops? My code, which I'm using is slow, and doesn't give the results I want:
for i=size(B,1)
if size(A(find(A==B,3),1)==0
B(i,2)=-100;
else
B(i,2)=max(A((A==B(i),2));
end
end
This code outputs -100 far too often and takes about 10 minutes to execute with my current dataset. A has about 1million pairs of data, and B about 150000.
I would be happy, if you could help.
I tried it in a single line operator, but matlab throws an error:
B(:,2)=max(A((A(:,1)==B(:,1)),2));
This results in Matlab throwing:
Error using ==
Matrix dimensions must agree.

Answers (2)

Warren
Warren on 21 Jul 2014
I'm not sure if this is any faster because I couldn't run your code. It puts NaN in places where you had -100. The idea is to create a data structure containing lists of elements of the second row of A that the elements of B correspond to. Setting up this data structure probably takes as long as what you had in mind, but once it is created, multiple statistics can be performed without much added time. The data structure should be pretty sparse compared to the original data.
[Locb,Loca]=ismember(A(:,1),B);
Loca=Loca(Locb); %%get rid of 0's
Adat=A(Locb,2); %%pick out members of second column that are in B
[~,emptyind]=setdiff(B,A(:,1)); %%To make cellfun work later need NaNs in Bcell
Bcell=cell(size(unique(B),1),1);
Bcell(emptyind)=repmat({[NaN]},length(emptyind),1);
for(i=1:length(Loca))
Bcell{Loca(i)}=[Bcell{Loca(i)};Adat(i)];
end
%%test on some statistical functions. Should return NaN in 4th row.
B(:,2)=cellfun(@min,Bcell);
B(:,3)=cellfun(@max,Bcell);
B(:,4)=cellfun(@mean,Bcell);
And the output looks like
B =
1.0000 0 1.0000 0.5000
4.0000 3.0000 4.0000 3.5000
6.0000 6.0000 7.0000 6.5000
6.5000 NaN NaN NaN
8.0000 1.0000 2.0000 1.5000

Jan
Jan on 22 Jul 2014
A cleaned version of your code:
B(:, 2) = NaN; % Avoid the pitfall of magic numbers like -100!
for k = 1:numel(B)
match = (A == B(k));
if any(match)
B(i,2) = max(A(match, 2));
end
end
This is lean and fast. The simpler the implementation, the less time has to be spent for programming and debugging.

Community Treasure Hunt

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

Start Hunting!