我有一个19×39双M,包含39种不同网络配置中19个网络节点的数据。每个列(即每个配置)显示了这些节点是如何组合成一个网络的。如果它们属于同一个网络,它们将具有相同的值。该值还指示有多少个网络。例如,M可能如下所示:
1 1 1
1 2 2
3 2 1
1 2 2
2 3 2
2 3 3
2 3 3
1 3 3
1 2 2
2 1 2
1 1 3
1 1 1
2 2 1
1 2 2
2 2 2
2 2 3
3 1 3
2 1 1
2 3 1这意味着,对于第1列(或配置1),在这一配置中有三个网络:包含节点1、2、4、8、9、11、12、14的网络1;包含节点5、6、7、10、13、15、16、18、19的网络2;包含节点3、17的网络3。现在,我要跨39种配置(或列)计算每个节点属于同一网络与每个剩余节点的次数。在此示例中,节点1与节点2属于同一网络一次,而节点4和9属于同一网络3次。我设想输出将是一个19x19矩阵,每个单元表示从y轴的节点在同一个网络中的多少倍,以及x轴中的节点。然后,对角线为39 (因为每个节点对于每个配置都属于同一网络本身)。有没有人建议如何有效地做到这一点?
发布于 2017-02-23 22:24:36
您应该能够使用bsxfun检查矩阵a与a的置换版本的相等性。然后,您可以在第二维空间中进行sum,给出给定网络中两个节点的共存数,并压缩结果得到一个2D矩阵。
squeeze(sum(bsxfun(@eq, a, permute(a, [3 2 1])), 2))输出中给定元素的行/列对应于两个节点在同一组中的次数。
作为一个简单的例子
a = [1 1 1
1 2 1;
2 2 1];
b = squeeze(sum(bsxfun(@eq, a, permute(a, [3 2 1])), 2))
% 3 2 1
% 2 3 2
% 1 2 3由此,节点1和2,b(1,2)在同一组中出现2次(网络1和3)。节点1和节点3,b(1,3)出现在同一网络中一次(网络3)。节点2和3,b(2,3),出现在同一网络中两次(网络2和3)。
如果您正在使用MATLAB R2016b或更新版本,则可以将其简化为
squeeze(sum(a == permute(a, [3 2 1]), 2));试图解释
与其考虑整个网络矩阵,不如先考虑第一个网络。我们希望比较分配给每个节点的组和分配给每个其他节点的组。我们可以使用bsxfun创建这个矩阵
tmp = bsxfun(@eq, a(:,1), a(:,1).')
% 1 1 0
% 1 1 0
% 0 0 1现在,如果我们对a的每个网络(列)这样做,我们将得到这些矩阵的N。
% Create a 3D matrix to hold co-occurance data
counts = zeros(size(a, 1), size(a, 1), size(a, 2));
for k = 1:size(a, 2)
counts(:,:,k) = bsxfun(@eq, a(:,k), a(:,k).');
end
% Now count how many times two nodes were placed in the same group
nSameGroup = sum(counts, 3);虽然这个循环可以工作,但是我们可以将第三个输入重新组合到bsxfun (使用permute),这样它就可以自动创建counts矩阵。
tmp = bsxfun(@eq, a, permute(a, [3 2 1]))
% tmp(:,:,1) =
% 1 1 1
% 1 0 1
% 0 0 1
% tmp(:,:,2) =
% 1 0 1
% 1 1 1
% 0 1 1
% tmp(:,:,3) =
% 0 0 1
% 0 1 1
% 1 1 1 然后,我们沿着第二维求和,计算出共发生的次数,并压缩结果得到一个二维矩阵。
squeeze(sum(tmp, 2))
% 3 2 1
% 2 3 2
% 1 2 3 https://stackoverflow.com/questions/42427133
复制相似问题