将带有 ids 的图形转换为其在 Matlab 中的索引
Transform a graph with ids to its index in Matlab
我有一个 Nx2 矩阵,其中包含来自图形的边。矩阵的索引对应于推特用户的 ID。他们的关系是转推状态(如果用户转推另一个用户)。在我的图表中完全存在 N 转推关系。用户数是 M。我想将图表的 id 从最初的 twitter id 转换为 1:M id。例如,将图形的第一个 id 替换为 1(在存在的每一行和每一列中)。我想这样做,而不是再次更改已经更改过的 id。我尝试将 for 循环与 find 函数结合使用,以便将 id 转换为索引。但是,我应该怎么做才能避免更改已经更改的项目?我知道我的代码是错误的:
counter = 0;
for index = 1:length(grph)
index1 = find(grph(:,1) == grph(index,1));
index2 = find(grph(:,2) == grph(index,2));
counter = counter+1;
grph(index1,1) = counter;
counter = counter+1;
grph(index2,2) = counter;
end
一个小例子说明了我想要的,如下:
35113 45010
5695 57711
22880 33193
22880 45010
43914 35113
期望的输出:
1 2
3 4
5 6
5 2
7 1
我现在无法测试,但这应该可以满足您的要求:
[~, ~, kk] = unique(A.','stable');
result = reshape(kk, fliplr(size(A))).';
您需要足够新的 Matlab 版本,以便 unique
具有 'stable'
选项。
如果您有通讯工具箱,第二行可以替换为
result = vec2mat(kk, size(A,2));
很简单。使用 unique
and reshape
的组合。假设您示例中的 ID 矩阵存储在 A
:
[~,~,B] = unique(A.', 'stable');
C = reshape(B, [size(A,2) size(A,1)]).';
A
将是 ID 矩阵,而 C
是您想要的输出。这是如何工作的,unique
的第三个输出将为您提供在 A
中遇到的每个值的唯一 ID 数组。之所以要先转置结果,是因为MATLAB是按列运算的,而你的结果需要按行运算。转置结果有效地做到了这一点。此外,您需要 'stable'
标志,以便我们按照遇到它们的顺序分配 ID。不做 'stable'
将首先 排序 A
中的值,然后分配 ID。
B
将不可避免地成为列向量,因此我们需要 reshape
将其返回到与您的输入 A
大小相同的矩阵。请注意,我需要通过结果的 转置 进行整形,因为 reshape
将在列之间进行操作。因为我们是按行操作的,所以我需要通过转置来重塑矩阵,然后转置该结果以获得您想要的输出。
使用示例:
A = [35113 45010
5695 57711
22880 33193
22880 45010
43914 35113]; %// Matrix defined by you
[~,~,B] = unique(A.', 'stable');
C = reshape(B, [size(A,2) size(A,1)]).';
C =
1 2
3 4
5 6
5 2
7 1
但是,如果不需要对 ID 进行排序并且您只想为每个节点 ID 分配 ID,那么您可以直接使用 unique
而无需 stable
标志。
现在,如果您想知道图表中的哪些 ID 分配给了输出矩阵中的哪些 ID,只需使用 unique
:
的第一个输出
[mapping, ~, B] = unique(A.', 'stable');
mapping
将为您提供矩阵中遇到的所有唯一 ID 的列表。他们的位置标识了用于将他们分配到 B
中的 ID。也就是说,运行这个,我们得到:
mapping =
35113
45010
5695
57711
22880
33193
43914
这意味着 A
中的 ID 35113 映射到 B
中的 1,A
中的 ID 45010 映射到 B
中的 2,依此类推。作为更详细的说明:
mappings = [(1:numel(mapping)).' mapping]
mappings =
1 35113
2 45010
3 5695
4 57711
5 22880
6 33193
7 43914
我有一个 Nx2 矩阵,其中包含来自图形的边。矩阵的索引对应于推特用户的 ID。他们的关系是转推状态(如果用户转推另一个用户)。在我的图表中完全存在 N 转推关系。用户数是 M。我想将图表的 id 从最初的 twitter id 转换为 1:M id。例如,将图形的第一个 id 替换为 1(在存在的每一行和每一列中)。我想这样做,而不是再次更改已经更改过的 id。我尝试将 for 循环与 find 函数结合使用,以便将 id 转换为索引。但是,我应该怎么做才能避免更改已经更改的项目?我知道我的代码是错误的:
counter = 0;
for index = 1:length(grph)
index1 = find(grph(:,1) == grph(index,1));
index2 = find(grph(:,2) == grph(index,2));
counter = counter+1;
grph(index1,1) = counter;
counter = counter+1;
grph(index2,2) = counter;
end
一个小例子说明了我想要的,如下:
35113 45010
5695 57711
22880 33193
22880 45010
43914 35113
期望的输出:
1 2
3 4
5 6
5 2
7 1
我现在无法测试,但这应该可以满足您的要求:
[~, ~, kk] = unique(A.','stable');
result = reshape(kk, fliplr(size(A))).';
您需要足够新的 Matlab 版本,以便 unique
具有 'stable'
选项。
如果您有通讯工具箱,第二行可以替换为
result = vec2mat(kk, size(A,2));
很简单。使用 unique
and reshape
的组合。假设您示例中的 ID 矩阵存储在 A
:
[~,~,B] = unique(A.', 'stable');
C = reshape(B, [size(A,2) size(A,1)]).';
A
将是 ID 矩阵,而 C
是您想要的输出。这是如何工作的,unique
的第三个输出将为您提供在 A
中遇到的每个值的唯一 ID 数组。之所以要先转置结果,是因为MATLAB是按列运算的,而你的结果需要按行运算。转置结果有效地做到了这一点。此外,您需要 'stable'
标志,以便我们按照遇到它们的顺序分配 ID。不做 'stable'
将首先 排序 A
中的值,然后分配 ID。
B
将不可避免地成为列向量,因此我们需要 reshape
将其返回到与您的输入 A
大小相同的矩阵。请注意,我需要通过结果的 转置 进行整形,因为 reshape
将在列之间进行操作。因为我们是按行操作的,所以我需要通过转置来重塑矩阵,然后转置该结果以获得您想要的输出。
使用示例:
A = [35113 45010
5695 57711
22880 33193
22880 45010
43914 35113]; %// Matrix defined by you
[~,~,B] = unique(A.', 'stable');
C = reshape(B, [size(A,2) size(A,1)]).';
C =
1 2
3 4
5 6
5 2
7 1
但是,如果不需要对 ID 进行排序并且您只想为每个节点 ID 分配 ID,那么您可以直接使用 unique
而无需 stable
标志。
现在,如果您想知道图表中的哪些 ID 分配给了输出矩阵中的哪些 ID,只需使用 unique
:
[mapping, ~, B] = unique(A.', 'stable');
mapping
将为您提供矩阵中遇到的所有唯一 ID 的列表。他们的位置标识了用于将他们分配到 B
中的 ID。也就是说,运行这个,我们得到:
mapping =
35113
45010
5695
57711
22880
33193
43914
这意味着 A
中的 ID 35113 映射到 B
中的 1,A
中的 ID 45010 映射到 B
中的 2,依此类推。作为更详细的说明:
mappings = [(1:numel(mapping)).' mapping]
mappings =
1 35113
2 45010
3 5695
4 57711
5 22880
6 33193
7 43914