Get indices of all rows containing a value - repeated or not

1 ビュー (過去 30 日間)
Tejas 2021 年 5 月 8 日
コメント済み: Tejas 2021 年 5 月 8 日
Say I have the following
id = (1:5)';
rng(1);
x = randperm(10,5)';
y = randperm(10,5)';
nodes = table(id,x,y)
connections = [1,2 ; 1,3 ; 2,4 ; 2,5 ; 3,5]
nodes =
5×3 table
id x y
__ _ _
1 3 6
2 4 2
3 7 5
4 1 3
5 2 1
connections =
1 2
1 3
2 4
2 5
3 5
I want to find the distances between the node pairs mentioned in connections (like between nodes 1 and 2, nodes 1 and 3, etc), based on their (x,y) values given in nodes table. And since the original data I have contains about 85000 connections, I'm looking to do this more efficiently than using a for loop for every pair. It works in the following way when the connections are unique:
connections = [1,3 ; 4,5];
x1 = nodes.x(ismember(nodes.id,connections(:,1)));
x2 = nodes.x(ismember(nodes.id,connections(:,2)));
y1 = nodes.y(ismember(nodes.id,connections(:,1)));
y2 = nodes.y(ismember(nodes.id,connections(:,2)));
% Chebyshev distance
dist = max([abs(x2-x1),abs(y2-y1)],[],2);
dist =
4
2
Thus, distance between nodes 1 and 3, and nodes 4 and 5, is 4 and 2 respectively. How can I do this as efficiently when there are repeated nodes in connections array? In the original case, I believe I should get
dist =
4
4
3
2
5

サインインしてコメントする。

採用された回答

Bruno Luong 2021 年 5 月 8 日
[c,~,J] = unique(sort(connections,2),'rows');
[i,~,I] = unique(c);
[~,j] = ismember(i, id);
xy = [x(j) y(j)];
I = reshape(I,[],2);
d = max(abs(xy(I(:,1),:)-xy(I(:,2),:)),[],2);
dist = d(J);
1 件のコメント表示非表示 なし
Tejas 2021 年 5 月 8 日
That works great for me. Much faster than a for loop. Thanks!

サインインしてコメントする。

R2020b

Community Treasure Hunt

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

Start Hunting!

Translated by