You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

如何为networkx.MultiDiGraph生成对应每个样本的多维邻接矩阵

如何为networkx.MultiDiGraph生成对应每个样本的多维邻接矩阵

你已经注意到,nx.to_numpy_arrayMultiDiGraph的默认行为是将同节点对的多条边权重求和,但你需要为每个sample_id单独生成一个邻接矩阵,最终拼成形状为(节点数, 节点数, 样本数)的3D数组。这里有两种实用的解决方案:

方法一:直接遍历边填充(高效推荐)

这种方法直接遍历图中所有边,根据每条边的sample_id将权重填充到3D数组的对应位置,适合节点和样本数较多的场景,执行效率更高:

import numpy as np
import networkx as nx
np.random.seed(123)

n_samples = 10

uv = [
    (1, 2),
    (2, 3),
    (3, 4),
    (4, 5),
    (5, 6)
]

G = nx.MultiDiGraph()
for u, v in uv:
    weights = np.random.uniform(0, 1, size=n_samples)
    G.add_edges_from([(u, v, dict(sample_id=s+1, weight=weights[s])) for s in range(n_samples)])

# 准备节点列表和索引映射,方便快速定位节点位置
nodelist = list(G.nodes)
n_nodes = len(nodelist)
node_to_idx = {node: idx for idx, node in enumerate(nodelist)}

# 初始化全零的3D邻接矩阵
A = np.zeros((n_nodes, n_nodes, n_samples))

# 遍历所有边,按sample_id将权重填充到对应位置
for u, v, attrs in G.edges(data=True):
    sample_idx = attrs['sample_id'] - 1  # 转换为0-based索引适配数组
    u_idx = node_to_idx[u]
    v_idx = node_to_idx[v]
    A[u_idx, v_idx, sample_idx] = attrs['weight']

# 验证数组形状
print(A.shape)  # 输出: (6, 6, 10)

方法二:利用nx.to_numpy_array的自定义权重逻辑

这种方法代码更简洁,通过为每个样本自定义权重提取规则,生成单个样本的邻接矩阵后再堆叠成3D数组,可读性更强:

# 基于你已构建好的G图
nodelist = list(G.nodes)
n_samples = 10

# 生成每个样本的邻接矩阵并沿最后一维堆叠
A = np.stack(
    [
        nx.to_numpy_array(
            G,
            nodelist=nodelist,
            # 自定义权重规则:只保留当前sample_id的边权重,其他边权重设为0
            weight=lambda u, v, d: d['weight'] if d['sample_id'] == s+1 else 0
        )
        for s in range(n_samples)
    ],
    axis=-1
)

print(A.shape)  # 输出: (6, 6, 10)

结果验证

你可以通过切片查看单个样本的邻接矩阵,比如查看第一个样本(对应sample_id=1)的矩阵:

print(A[:, :, 0])

这会输出仅包含对应样本边权重的邻接矩阵,完全避免了权重求和的默认行为,符合你的需求。

备注:内容来源于stack exchange,提问作者HJA24

火山引擎 最新活动