Apache Spark GraphX连接组件

时间:2015-05-25 21:24:28

标签: apache-spark spark-graphx

如何使用子图函数来获取仅包含特定连接组件的顶点和边的图形?假设我知道连接组件ID,最终目标是基于连接组件创建新图。我想保留原始图表中的顶点属性。

2 个答案:

答案 0 :(得分:6)

您必须将图表与组件ID一起加入到原始图表中,按组件ID过滤(获取子图),然后丢弃组件ID。

import scala.reflect._
import org.apache.spark.graphx._
import org.apache.spark.graphx.lib.ConnectedComponents

def getComponent[VD: ClassTag, ED: ClassTag](
    g: Graph[VD, ED], component: VertexId): Graph[VD, ED] = {
  val cc: Graph[VertexId, ED] = ConnectedComponents.run(g)
  // Join component ID to the original graph.
  val joined = g.outerJoinVertices(cc.vertices) {
    (vid, vd, cc) => (vd, cc)
  }
  // Filter by component ID.
  val filtered = joined.subgraph(vpred = {
    (vid, vdcc) => vdcc._2 == Some(component)
  })
  // Discard component IDs.
  filtered.mapVertices {
    (vid, vdcc) => vdcc._1
  }
}

答案 1 :(得分:2)

我提出你的问题,给定源图中的VertexId,创建一个新图,其中节点和边从源图中连接到此VertexId。

鉴于此,这就是我要做的事情:

val targetVertexId = ...
val graph = Graph(..., ...)
val newGraph = Graph(
  graph.vertices.filter{case (vid,attr) => vid == targetVertexId} ++
  graph.collectNeighbors(EdgeDirection.Either)
    .filter{ case (vid,arr) => vid == targetVertexId}
    .flatMap{ case (vid,arr) => arr},
  graph.edges
).subgraph(vpred = { case (vid,attr) => attr != null})

需要注意的事项:

您可以根据需要将EdgeDirection.Either更改为EdgeDirection.InEdgeDirection.Out

最后的.subgraph会删除属性设置为null的所有顶点。如果原始val graph的顶点属性设置为null,则无效。否则这是有效的,而无需事先知道Vertex属性类型。