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

基于Apache Spark GraphX生成图后如何获取邻接表?

嗨!你已经用GraphX成功构建了图结构,要生成邻接表其实GraphX提供了很便捷的方式,下面给你两种实用的实现方案,适配不同的需求:

1. 生成带边属性的完整邻接表

如果你需要同时保留邻接节点和对应的边属性,用triplets API是最直接的选择——它能直接获取源节点、目标节点和边属性的三元组信息,我们只需要按源节点分组即可:

// 基于Triplets生成带边属性的邻接表
val adjacencyListWithAttributes = graphx.triplets
  // 把源节点ID作为Key,目标节点ID+边属性作为Value
  .map(triplet => (triplet.srcId, (triplet.dstId, triplet.attr)))
  // 按源节点分组,收集所有邻接关系
  .groupByKey()
  // 将迭代器转为List,方便查看和后续处理
  .mapValues(neighborIter => neighborIter.toList)

// 打印结果验证
adjacencyListWithAttributes.foreach { case (sourceNodeId, neighbors) =>
  val neighborStr = neighbors.map(n => s"节点ID: ${n._1}, 关联边属性: ${n._2}").mkString(" | ")
  println(s"源节点 $sourceNodeId 的邻接关系:$neighborStr")
}

2. 仅生成邻接节点ID的精简邻接表

如果只需要邻接节点的ID,不需要边属性,可以直接基于边数据集处理,步骤更简洁:

// 生成仅包含邻接节点ID的邻接表
val adjacencyListOnlyIds = graphx.edges
  // 提取源节点ID和目标节点ID
  .map(edge => (edge.srcId, edge.dstId))
  // 按源节点分组
  .groupByKey()
  // 转成List并去重(避免重复边导致的重复邻接节点)
  .mapValues(dstIdIter => dstIdIter.toList.distinct)

// 打印结果验证
adjacencyListOnlyIds.foreach { case (sourceNodeId, dstIds) =>
  println(s"源节点 $sourceNodeId 的邻接节点ID:${dstIds.mkString(", ")}")
}

额外补充:无向图的邻接表处理

如果你的图是无向图(即A→B的边同时意味着B→A),需要先补全反向边,再生成邻接表:

// 生成无向图的边集(包含原边和反向边)
val undirectedEdges = graphx.edges.flatMap(edge => List(edge, Edge(edge.dstId, edge.srcId, edge.attr)))
// 构建无向图
val undirectedGraph = Graph(graphx.vertices, undirectedEdges)

// 用第一种方法生成无向图的邻接表
val undirectedAdjacencyList = undirectedGraph.triplets
  .map(t => (t.srcId, (t.dstId, t.attr)))
  .groupByKey()
  .mapValues(_.toList)

这样就能根据你的需求生成对应的邻接表啦!

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.28 07:06:59