Search parallel rows of a structures for common it

2020-04-30 09:58发布

问题:

I've stored (row,col,val) information of

 key1:         (1,1) (1,2) (1,3) (4,2) (3,4)  
 attribute1:    2      3    4      2     5  

as follows:

 Structure A1:
 key row1:      1  1  1  4  3 
 key col1:      1  2  3  2  4
 attribute1:    2  3  4  2  5

Similarly, for structure A2

 Structure A2:
 key row2:      2  2  1  3 
 key col2:      1  2  3  4
 attribute2:    1  0  1  5 

Now, I'd like to be able to search for common entries in both row and column key items between structure A1 and A2 simultaneously. That is conceptually find [common_item, index]=intersect([row2,col2],[row1,col1]). I'd like the final result is insensitive to the order of row and col. So, in my example (1,2) key value is equal to (2,1) value. Then, the attribute value of common entries should be added together. The intended result is

 Structure Result:     //it recognizes (1,2) and(2,1) are the same.
 key row:      2  1  3 
 key col:      1  3  4
 attribute:    4  5  10 

How should I proceed to search for common entries and do some operation ? ismember function can search for common item just in one row and if there are multiple occurrence, it just count the first. In addition, as I said, I want it to be order insensitive in key values.

Thanks for any help.

回答1:

first use sort to achieve row-col order insensitivity, next use unique to handle row-col duplicates within each structure, and finally use ismember (with 'rows') to find common keys between the structures. note that I added an inner duplication to each structure to show the second stage effect:

% struct1
row1 = [1  1  1  2  4  3];
col1 = [1  2  3  1  2  4];
att1 = [2  3  4  6  2  5];
% struct2
row2 = [2  2  1  3  3];
col2 = [1  2  3  1  4];
att2 = [1  0  1  1  5];
% sort in 2nd dimension to get row-column indexes insensitive for order
idx1 = sort([row1(:) col1(:)],2);
idx2 = sort([row2(:) col2(:)],2);
% search for duplicates inside each struct
[idx1,~,bins1] = unique(idx1,'rows','stable');
att1 = accumarray(bins1,att1);
[idx2,~,bins2] = unique(idx2,'rows','stable');
att2 = accumarray(bins2,att2);
% search common entries
common1 = ismember(idx1,idx2,'rows');
row = idx1(common1,1);
col = idx1(common1,2);
common2 = ismember(idx2,[row col],'rows');
% add common values
att = att1(common1) + att2(common2);
Result.row = row';
Result.col = col';
Result.attribute = att';
disp(Result)

and you get:

Result = 
          row: [1 1 3]
          col: [2 3 4]
    attribute: [10 6 10]