You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

高效实现DataFrame单元格与邻域比较并构建NetworkX有向图

高效实现DataFrame邻域有向边构建方案

核心思路:用向量化运算替代双重循环

3000×3000的DataFrame有900万个单元格,双重循环逐个遍历、判断并添加边的方式效率极低。推荐通过numpy向量化批量生成所有符合条件的边对,再一次性导入NetworkX,从计算和IO层面大幅降低开销。

具体实现步骤

1. 映射坐标与单元格值

先把DataFrame的行/列标签转换成可批量处理的坐标元组,同时提取所有单元格的值:

import pandas as pd
import numpy as np
import networkx as nx

# 假设你的DataFrame为df
# 生成所有单元格的坐标元组列表
coords = [(row, col) for row in df.index for col in df.columns]
# 提取对应的值数组,顺序与coords完全匹配
values = df.values.flatten()

2. 批量生成邻域索引

先把坐标转换成数字索引,方便计算邻域位置(这里以8邻域为例,可根据需求调整为4邻域):

# 将行/列标签映射为数字索引
row_to_idx = {row: i for i, row in enumerate(df.index)}
col_to_idx = {col: j for j, col in enumerate(df.columns)}

# 把坐标转换成二维索引数组 (总单元格数, 2)
idx_array = np.array([[row_to_idx[row], col_to_idx[col]] for row, col in coords])

# 定义8邻域的偏移量(去掉对角就是4邻域)
neighbor_offsets = [(-1,-1), (-1,0), (-1,1),
                    (0,-1),          (0,1),
                    (1,-1),  (1,0), (1,1)]

3. 向量化筛选符合条件的边对

利用numpy广播机制批量计算邻域并判断值的大小关系:

# 扩展索引数组,为每个邻域偏移创建副本 (8, 总单元格数, 2)
neighbor_idx = idx_array[None, :, :] + np.array(neighbor_offsets)[:, None, :]

# 过滤超出DataFrame边界的无效邻域
valid_mask = (neighbor_idx[:, :, 0] >= 0) & (neighbor_idx[:, :, 0] < len(df.index)) & \
             (neighbor_idx[:, :, 1] >= 0) & (neighbor_idx[:, :, 1] < len(df.columns))

# 把有效邻域转换成values数组的一维索引
flat_neighbor_idx = neighbor_idx[:, :, 0] * len(df.columns) + neighbor_idx[:, :, 1]
flat_neighbor_idx[~valid_mask] = -1  # 标记无效邻域

# 批量比较当前值与邻域值,筛选出当前值更大的情况
current_values = values[None, :]
neighbor_values = values[flat_neighbor_idx]
edge_mask = (current_values > neighbor_values) & valid_mask

# 收集所有有效边对
edges = []
for i in range(len(neighbor_offsets)):
    src_indices = np.where(edge_mask[i])[0]
    dst_indices = flat_neighbor_idx[i][edge_mask[i]]
    edges.extend([(coords[src], coords[dst]) for src, dst in zip(src_indices, dst_indices)])

4. 批量导入NetworkX

避免逐个调用add_edge,直接用add_edges_from一次性添加所有边:

G = nx.DiGraph()
G.add_edges_from(edges)

额外优化:稀疏矩阵降内存

如果符合条件的边占比不高,可通过稀疏矩阵存储邻接关系,进一步节省内存:

from scipy.sparse import coo_matrix

# 生成源和目标的一维索引
src_idx = np.repeat(np.arange(len(coords)), len(neighbor_offsets))
dst_idx = flat_neighbor_idx.flatten()

# 过滤无效边与不符合条件的边
valid_edge_mask = edge_mask.flatten() & (dst_idx != -1)
src_idx = src_idx[valid_edge_mask]
dst_idx = dst_idx[valid_edge_mask]

# 创建稀疏邻接矩阵并转换为NetworkX图
adj_matrix = coo_matrix((np.ones(len(src_idx)), (src_idx, dst_idx)), shape=(len(coords), len(coords)))
G = nx.from_scipy_sparse_array(adj_matrix, create_using=nx.DiGraph())
# 将节点索引映射回原坐标元组
nx.relabel_nodes(G, {i: coords[i] for i in range(len(coords))}, copy=False)

内容的提问来源于stack exchange,提问作者Majed elmohands

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.17 17:55:28