加入两个rdds来建立一个邻接列表

时间:2016-04-15 14:36:26

标签: python apache-spark pyspark rdd

我是新来的火花,我有两个rdds我想加入制作邻接列表

RDD1 (nodes): (a, b, c, d, e, f, g)

RDD2 (Edges): ((a,b), (a,e), (f, a), (k,l) ...)

现在我想加入这两个rdds来创建一个像这样的邻接列表

( (a,(b,e,..)), (b,(f,....), (g()) ,...)
#assuming that g is not connected to any node , also filter (k,l) because k and l are not in the nodes rdd

以及稍后我需要总共查找节点数和边数。

1 个答案:

答案 0 :(得分:1)

因此,如果我理解正确,您希望有一个邻接列表,其中最终的RDD由键值对组成,键是节点,值是列表的边缘。也许下面显示的是您的想法?虽然我相信如果你想在你的最终RDD中显示'g',那么将它作为('g','')放在你的边缘列表中是有意义的,因为你希望传达它没有边缘。

要加入,我们需要将节点列表转换为一对RDD,因此首先我们并行化以创建RDD,然后映射一个虚拟值,以便我们有键值对。

现在我们可以将两个RDD相互连接起来,结果将只是两个RDD中存在的密钥,在这种情况下为'a'和'f'。最后,我们将我们添加的虚拟值剥离到节点RDD和groupByKey,以将我们的值组合在一起。

nodes = ['a', 'b', 'c', 'd', 'e', 'f', 'g']
edges = [('a','b'), ('a','e'), ('f', 'a'), ('k','l')]
nodesRDD = sc.parallelize(nodes).map(lambda n: (n, ''))
edgesRDD = sc.parallelize(edges)
joinedRDD = nodesRDD.join(edgesRDD).map(lambda tup: (tup[0], tup[1][1]))
groupedRDD = joinedRDD.groupByKey()

groupedRDD.map(lambda x : (x[0], list(x[1]))).collect()

出[146]:[('f',['a']),('a',['b','e'])]

Count类似但现在我们不关心实际的节点值,只关心它们的计数:

nodes = ['a', 'b', 'c', 'd', 'e', 'f', 'g']
edges = [('a','b'), ('a','e'), ('f', 'a'), ('k','l')]
nodesRDD = sc.parallelize(nodes).map(lambda n: (n, 0))
edgesRDD = sc.parallelize(edges).map(lambda tup: (tup[0], 1))
joinedRDD = nodesRDD.join(edgesRDD).map(lambda tup: (tup[0], tup[1][1]))
reducedRDD = joinedRDD.reduceByKey(lambda a, b: a + b)

reducedRDD.collect()

Out [159]:[('f',1),('a',2)]