1
這個問題是前一個問題的「續集」。我新來激發graphx和scala,我想知道如何執行下面的操作。圖形之間的結構操作符
我該如何合併兩個圖形進入一個新的圖形,使新的圖形具有以下屬性:
兩個圖形的共同邊緣的屬性平均(或更一般的方式,應用邊緣屬性之間的平均函數(邊緣屬性是類型雙))
我們認爲共同的邊緣=相同srcId和相同dstId,並且頂點和邊是唯一的。
這個問題是前一個問題的「續集」。我新來激發graphx和scala,我想知道如何執行下面的操作。圖形之間的結構操作符
我該如何合併兩個圖形進入一個新的圖形,使新的圖形具有以下屬性:
兩個圖形的共同邊緣的屬性平均(或更一般的方式,應用邊緣屬性之間的平均函數(邊緣屬性是類型雙))
我們認爲共同的邊緣=相同srcId和相同dstId,並且頂點和邊是唯一的。
假設你只有兩個圖,並都含有相同的一組頂點,而不可以用結合邊緣和新的圖形使用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
,然後映射,需要所有的值一次,如中位數。
因爲我很喜歡這個答案。考慮性能問題而不考慮'combineByKey'更合適。你怎麼看? – eliasah
而不是'aggregateByKey'? – zero323
不是'groupByKey' – eliasah