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

Python中基于DataFrame两列构建网络并添加聚类ID列的方法

刚好我之前处理过类似的需求,给你分享两个高效的实现方案,分别用igraph和networkx结合pandas,解决你之前遇到的速度慢的问题:

方案一:用igraph实现(高效首选)

igraph的底层是用C实现的,处理大规模图数据的速度比纯Python实现的库快很多,完全能对标你R语言里的igraph包效率。具体步骤如下:

  1. 导入所需库
  2. 从DataFrame的边列直接构建无向图
  3. 获取连通分量(也就是你说的聚类)
  4. 建立节点到聚类ID的映射,用向量化操作快速赋值回原DataFrame

完整代码示例:

import pandas as pd
import igraph as ig

# 模拟你的原始DataFrame
df = pd.DataFrame({
    "col1": ["A", "B", "C", "D", "E", "F"],
    "col2": ["B", "C", "A", "E", "D", "G"]
})

# 从边数据构建无向图,自动识别所有节点
g = ig.Graph.DataFrame(df[["col1", "col2"]], directed=False)

# 获取连通分量聚类结果
clusters = g.clusters()

# 创建节点到聚类ID的映射Series,索引是节点名,值是聚类ID
cluster_map = pd.Series(clusters.membership, index=g.vs["name"])

# 快速将聚类ID映射回原DataFrame的col1列对应的行
df["cluId"] = df["col1"].map(cluster_map)

为什么这个方案快?

  • igraph的图构建和聚类计算都是底层C实现,处理百万级边也毫无压力
  • 用pd.Series.map()做向量化映射,比循环遍历每一行快几个数量级
方案二:用networkx实现(灵活兼容)

如果你更倾向于用networkx,也可以用高效的方式实现,避免之前的慢速度问题。核心是一次性构建节点到聚类ID的字典映射,而不是逐个节点查找:

完整代码示例:

import pandas as pd
import networkx as nx

# 同样的模拟DataFrame
df = pd.DataFrame({
    "col1": ["A", "B", "C", "D", "E", "F"],
    "col2": ["B", "C", "A", "E", "D", "G"]
})

# 从DataFrame边列构建无向图
g = nx.from_pandas_edgelist(df, source="col1", target="col2", create_using=nx.Graph())

# 获取所有连通分量,用字典推导式快速生成节点-聚类ID映射
cluster_map = {}
for cluster_id, component in enumerate(nx.connected_components(g)):
    for node in component:
        cluster_map[node] = cluster_id

# 映射回原DataFrame
df["cluId"] = df["col1"].map(cluster_map)

优化点说明:

  • 用nx.connected_components()批量获取所有连通分量,避免重复遍历图
  • 字典推导式一次性完成所有节点的ID赋值,比循环每行去查询聚类快很多

注意事项

不管用哪种方案,都要确保col1和col2的节点类型一致(比如都是字符串或都是整数),如果类型不统一,可以先转成字符串:

df["col1"] = df["col1"].astype(str)
df["col2"] = df["col2"].astype(str)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.21 06:45:43