【问题标题】:join two rdds to make an adjacency list加入两个 rdds 做一个邻接表
【发布时间】:2016-10-30 03:45:01
【问题描述】:

我是 spark 新手,我想加入两个 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

稍后我需要找到节点和边的总数。

【问题讨论】:

  • 能否澄清一下:需要找到节点和边的总数?是不是说邻接表只是一个临时结构?
  • 表示我需要计数和邻接表。
  • 好的,你试过了吗?虽然 PySpark 中没有有效的解决方案,但这只是对内置方法的一次调用。
  • 是的,我取得了一些进展。我现在有一个带有 (a ,(a,e),(a,b)..) 的 rdd 现在我想将其更改为 (a,(e,b,...)

标签: python apache-spark pyspark rdd


【解决方案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()

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

【讨论】:

  • 不要使用reduceByKey 连接列表。它永远不会比groupByKey 好,而且在 JVM 上明显更差。
  • 我只是将字符作为示例,这很有趣,它们在实际问题中是字符串,现在我得到了这样的东西 ((string1,[s,t,r,i,n, g,2,...])....)
  • @zero323 好点,我已经编辑了 groupByKey 的转换以防止不必要的垃圾收集。
  • @AzeemAkhter 有趣我刚刚用所有值作为字符串进行了测试,但我仍然得到正确的结果,也许试试我刚刚编辑的版本,现在使用 groupByKey?
  • 是的,它现在工作正常,但是在最终的邻接列表中,而不是只有一个键连接到的节点,我有带有 '' 和另一个节点的元组。我怎样才能使它只包含节点名称?我怀疑这里有一张地图,但如何映射一个键的多个值
猜你喜欢
  • 2016-03-25
  • 2020-07-26
  • 1970-01-01
  • 2017-09-06
  • 1970-01-01
  • 1970-01-01
  • 2019-09-08
  • 2013-11-27
  • 2015-06-04
相关资源
最近更新 更多