Splitting Matrix based on another matrix

I have two matrices as follows.
popx=[52.647 10.912 2.389
52.564 10.911 2.389
52.569 10.912 2.389
52.569 10.912 2.389
52.569 10.913 2.389
52.569 10.913 2.389];
cx=[52.646 10.912 2.389
52.564 10.911 2.389
52.569 10.913 2.403
52.570 10.912 2.389
52.569 10.913 2.389
52.569 10.912 2.389];
Now, I want to split cx into two matrirces as per the following-
  1. rows which are UNIQUE with respect to popx.
  2. rows wich are NOT UNIQUE with respect to cx.
Finally, I will again merge these two matrices which will be equivalent to cx (i do not mind if the order of rows are diffferent).
How can I do this?

5 Comments

NOTE: intersect may not work here as there can be repition of rows.
Please give the intended result for the example you've posted.
A = [52.6460 10.9120 2.3890
52.5690 10.9130 2.4030
52.5700 10.9120 2.3890]; % unique in cx w.r.t popx
B = [52.5640 10.9110 2.3890
52.5690 10.9130 2.3890
52.5690 10.9120 2.3890] % not unique in cx w.r.t. popx; I need the index of these rows w.r.t. popx as well. these indixes will be used somewhere else.
C=[52.6460 10.9120 2.3890
52.5690 10.9130 2.4030
52.5700 10.9120 2.3890
52.5640 10.9110 2.3890
52.5690 10.9130 2.3890
52.5690 10.9120 2.3890] % Combined matrix
WHat does it mean to be "unique in cx with respect to popx"?
It means that, the rows which are in cx but not in popx.

Sign in to comment.

 Accepted Answer

I would like to thank Matt J for helping me solve the problem. My sincere gratitude to him.
Meanwhile, this is the way how I have solved the issue-
archive = unique(popx,"rows","stable");
ia=find(~ismember(cx,popx,'rows')==1);
A = cx(ia,:); % A is the matrix of rows which are present in cx but not present in popx
ia1=setdiff(1:size(cx,1),ia);
B0=cx(ia1,:);
if size(B0,2)~=0
[~,ib]=ismember(B0,archive,"rows");
end
B=archive(ib,:);
C = [A;B];

More Answers (3)

This might be what you want.
popx=[52.647 10.912 2.389
52.564 10.911 2.389
52.569 10.912 2.389
52.569 10.912 2.389
52.569 10.913 2.389
52.569 10.913 2.389];
cx=[52.646 10.912 2.389
52.564 10.911 2.389
52.569 10.913 2.403
52.570 10.912 2.389
52.569 10.913 2.389
52.569 10.912 2.389];
[~,~,Gp]=unique(popx,'rows');
[~,~,Gc]=unique(cx,'rows');
Hp=histcounts(Gp,1:max(Gp)+1);
Hc=histcounts(Gc,1:max(Gc)+1);
crit1=(Hp==1);
crit2=(Hc>1);
M1=cx(crit1(Gp),:)
M1 = 2×3
52.6460 10.9120 2.3890 52.5640 10.9110 2.3890
M2=cx(crit2(Gc),:)
M2 = 0×3 empty double matrix
result=[M1,M2]
result = 2×3
52.6460 10.9120 2.3890 52.5640 10.9110 2.3890
This can be a way, I think. Need to think about the extreme cases though.
[A,ia]=setdiff(cx,popx,"rows","stable");
ia1=setdiff(1:size(cx,1),ia);
ic=find((ismember(popx,cx,"rows"))~=0);
if size(ia1,2)==size(unique(popx(ic,:),"rows"),1)
[~,~,ib]=intersect(cx,popx,'rows','stable');
else
ib=find((ismember(popx,cx,"rows"))~=0);
end
B=popx(ib,:);
C=[A;B];
Matt J
Matt J on 19 Oct 2022
Edited: Matt J on 19 Oct 2022
popx=[52.647 10.912 2.389
52.564 10.911 2.389
52.569 10.912 2.389
52.569 10.912 2.389
52.569 10.913 2.389
52.569 10.913 2.389];
cx=[52.646 10.912 2.389
52.564 10.911 2.389
52.569 10.913 2.403
52.570 10.912 2.389
52.569 10.913 2.389
52.569 10.912 2.389];
[A,ia]=setdiff(cx,popx,'rows')
B=setdiff(cx,A,'rows')
C=[A;B]

16 Comments

well, this does not always work. If there is repitation, it fails. For example, let's say there are 3 rows which are common in popx and cx. Among these 3 rows, two rows are identical. Using setdiff/intersect function will give me the unique rows. But I want all three common rows.
And most importantly, I need the indices of rows of B with respect to popx.
Matt J
Matt J on 19 Oct 2022
Edited: Matt J on 19 Oct 2022
What is the meaning of " the indices of rows of B with respect to popx"? B are the remaining rows in cx that are not in A. They have nothing to do with popx.
It is true that "B are the remaining rows in cx that are not in A". But B is also subset of popx. Please look at the venn diagram. It may make sense.
A0=setdiff(cx,popx,'rows');
B0=setdiff(cx,A0,'rows');
loc=ismember(cx,A0,'rows');
A=cx(loc,:);
loc=ismember(popx,B0,'rows');
B=popx(loc,:); %loc contains desired indices into popx
Okay, let me try this.
Will it be A0 in 2nd line?
Yes, I fixed it.
I appreciate your effort, mate. But unfortunately, it does not work in all cases.
Try with these values-
popx=[ 52.6440 10.8560 2.3890
52.6450 10.9110 2.3890
52.6470 10.9120 2.3890
52.6470 10.9120 2.3890
52.6470 10.9120 2.3890
52.6460 10.9120 2.3890];
cx=[52.6470 10.8560 2.4330
52.6450 10.9110 2.3890
53.1770 10.7480 2.3890
52.6440 10.7950 2.3890
52.6470 10.9120 2.3890
52.6470 10.9120 2.3890];
Here,
[A;B] should be equal to cx. (if the order of rows are different, there is no problem).
This is working untill I find some other extreme case-
archive = unique(popx,"rows","stable");
[A,ia]=setdiff(cx,popx,"rows","stable");
ia1=setdiff(1:size(cx,1),ia);
B0=cx(ia1,:);
ib=find((ismember(archive,B0,"rows"))~=0);
B=archive(ib,:);
C=[A;B];
A0=setdiff(cx,popx,'rows');
B0=setdiff(cx,A0,'rows');
loc=ismember(cx,A0,'rows');
A=cx(loc,:);
loc=ismember(cx,B0,'rows');
B=cx(loc,:); %loc contains desired indices into popx
C=[A;B];
popxIndices=ismember(popx,C,'rows')
Mate, Please help me solve the following. Then my whole problem will be solved. I will comment it once it is solved.
B= [ 52.6450 10.9110 2.3890
52.6470 10.9120 2.3890
52.6470 10.9120 2.3890]
archive = [ 52.6440 10.8560 2.3890
52.6450 10.9110 2.3890
52.6470 10.9120 2.3890
52.6460 10.9120 2.3890]
how can I find the corresponding row index of archive for each row of B?
i.e. I want the answer as-
id = [2 3 3]
It means that,
B(1,:)=archive(2,:)
B(2,:)=archive(3,:)
B(3,:)=archive(3,:)
[~,id]=ismember(B,archive,"rows")

Sign in to comment.

Products

Release

R2022b

Tags

Community Treasure Hunt

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

Start Hunting!