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 个评论

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.

请先登录,再进行评论。

 采纳的回答

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];

更多回答(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];
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 个评论

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.
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
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,:)

请先登录,再进行评论。

类别

帮助中心File Exchange 中查找有关 Matrix Indexing 的更多信息

产品

版本

R2022b

标签

Community Treasure Hunt

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

Start Hunting!

Translated by