Finding couple of values in other vector of values

Say I have a list of couple of values and another list of couple of values which belong to Xd,Yd but that I don't know. How do I efficiently get the list of index locating xv,yv in Xd,Yd ?
All I could find so far is using a loop which is very slow...
[Xd,Yd] = meshgrid(linspace(0,100,101),linspace(0,100,101));
Xd=Xd(:);
Yd=Yd(:);
xv = randi(101,[20,1]);
yv = randi(101,[20,1]);
for i=1:length(xv)
Iv(i) = find(ismember(Xd,xv(i)) & ismember(Yd,yv(i))==1);
end
EDIT : this is a dummy exemple. I need to do that with a very long vectors of values.

 Accepted Answer

% I have three vectors of values vi on different zones (xi,yi) with overlapping areas i.e. they share some
% exact positions
% I build the global domain
Xd = [x1 x2 x3];
Yd = [y1 y2 y3];
% I remove the duplicates
[~,inds,~] = unique([Xd,Yd],'rows','stable');
Xd = Xd(inds);
Yd = Yd(inds);
% I put each zone on the global domain
% this means that I need to find where (xi,yi) are locatedd in (Xd,Yd)
% hence the ismember over all couples
v1g = nan(size(Xd));
Iin = ismember([Xd,Yd],[x1,y1],'rows')
v1g(Iin) = v1;
v2g = nan(size(Xd));
Iin = ismember([Xd,Yd],[x2,y2],'rows')
v2g(Iin) = v2;
v3g = nan(size(Xd));
Iin = ismember([Xd,Yd],[x3,y3],'rows')
v3g(Iin) = v3;
% I get the mean
meand = mean([v1g v2g v3g],2,'omitnan');

More Answers (1)

Takes 1 millisecond (0.000897 seconds) on my computer. Why is that not fast enough for you?
There is a problem with the code in that sometimes it finds no match. What do you want to do in that situation? Here is a suggestion:
[Xd,Yd] = meshgrid(linspace(0,100,101),linspace(0,100,101));
Xd=Xd(:);
Yd=Yd(:);
xv = randi(101,[20,1]);
yv = randi(101,[20,1]);
tic
Iv = nan(length(xv), 1);
for k = 1 : length(xv)
locations = find(ismember(Xd,xv(k)) & ismember(Yd,yv(k))==1);
if ~isempty(locations)
Iv(k) = locations;
end
end
toc
Elapsed time is 0.013204 seconds.

6 Comments

Sorry I dedited the question. I actually need to do that using a very long Xd so the loop is taken ages...
I was hoping that instead of calling a large number of times ismember I could call it only once by doing some manipulation of the data to get the condition I need.
If you're dealing with images there are built in functions to do a lot of this kind of stuff, but if you have vectors, you are pretty much limited to things like ==, contains(), ismember(), strfind(), etc. Maybe if I knew more about the actual application instead of just your attempted code at a simplified situation I could offer more.
What, exactly, is "ages" for you? Hours or days? How big is your actual data? How many gigabytes? How many rows and columns?
In this case I can't turn my data points in an image so indeed I'm stuck with vectors. It can take minutes which is unfortunately too long as I need to compute this many times. My real case is that I have three different zones defined by positions and accompanying value (xz1,yz1,vz1), (xz2,yz2,vz2) etc and I need to fuse them and calculate the mean of vz on the global zone because these zones have overlapping areas. Trying to do that basically led me to build the global zone Xd=(xz1+xz2+xz3) then remove the duplicates and then run the ismember loop to locate xzi in Xd and compute the means. But indeed maybe there is some other and better way.
I'm not sure I'm visualizing this correctly. Do you have a diagram?
Maybe unique([x,y,z], 'rows') could help you identify duplicates and unique rows.
This is indeed what I do to remove the duplicate and I realized I actually can do the same with ismember....so thank you, the results are now given almost instantaneously ! I added the complete answer below.

Sign in to comment.

Categories

Community Treasure Hunt

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

Start Hunting!