图之间的结构运算符

时间:2015-08-28 15:05:22

标签: scala apache-spark spark-graphx

这个问题是"续集"到前一个。我是新手来激发graphx和scala,我想知道如何执行下面的操作。

如何将两个图表合并到一个新图表中,以便新图表具有以下属性:

  

两个图的公共边的属性是平均的(或者以更一般的方式,在边属性之间应用平均函数(边属性是double类型))

我们认为公共边=相同的srcId和相同的dstId,顶点和边是唯一的。

1 个答案:

答案 0 :(得分:2)

假设您只有两个图形,并且两个图形都包含相同的顶点集而没有重复的边缘,则可以使用组合边并在新图上使用 List<Event> temp = []; ids.each { id -> temp << events.find { it.id == id } } events = temp; 方法:

groupEdges

或更普遍:

val graph1: Graph[T,Double] = ???
val graph2: Graph[T,Double] = ???

Graph(graph1.vertices, graph1.edges.union(graph2.edges))
  .groupEdges((val1, val2) => (val1 + val2) / 2.0)

如果这还不够,您可以组合值并从头开始创建新图表:

Graph(graph1.vertices, graph1.edges.union(graph2.edges))
  .mapEdges(e => (e.attr, 1.0))
  .groupEdges((val1, val2) => (val1._1 + val2._1, val1._2 + val2._2))
  .mapEdges(e => e.attr._1 / e.attr._2)

其中def edgeToPair (e: Edge[Double]) = ((e.srcId, e.dstId), e.attr) val pairs1 = graph1.edges.map(edgeToPair) val pairs2 = graph2.edges.map(edgeToPair) // Combine edges val newEdges = pairs1.union(pairs2) .aggregateByKey((0.0, 0.0))( (acc, e) => (acc._1 + e, acc._2 + 1.0), (acc1, acc2) => (acc1._1 + acc2._1, acc1._2 + acc2._2) ).map{case ((srcId, dstId), (acc, count)) => Edge(srcId, dstId, acc / count)} // Combine vertices assuming there are no conflicts // like different labels val newVertices = graph1.vertices.union(graph2.vertices).distinct // Create new graph val newGraph = Graph(newVertices, newEdges) 可以替换为aggregateByKey,后跟需要所有值的映射,例如中位数。