图之间的结构算子

艾尔·詹森(Al Jenssen)

这个问题是上一个问题的“续集”。我是sparkgraphx和scala的新手,我想知道如何执行以下操作。

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

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

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

零323

假设您只有两个图,并且都包含相同的一组顶点而没有重复的边,则可以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可以被替换groupByKey,随后,需要的所有值在一次像中位映射。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章