如何在spark中平面嵌套嵌套列表

时间:2016-12-13 09:57:49

标签: scala apache-spark

我在火花中有一个RDD,看起来像这样 -

[Foo1, Bar[bar1,bar2]]

Bar对象有一个getList方法,可以分别返回列表[bar11,bar12,bar13]和[bar21,bar22]。我希望输出看起来像这样 -

[Foo1, [bar11, bar12, bar13, bar21, bar22]]

我能想到的方法是这样的 -

my_rdd.map(x => (x._1,x._2.getList))
    .flatmap{
        case(x,y) => y.map(x, _)
    }

第一个地图操作是返回Foo1和所有列表。但是,除此之外,我无法将它们弄平。

2 个答案:

答案 0 :(得分:1)

您可以使用一行执行此操作:

my_rdd.mapValues(_.flatMap(_.getList))

另一个答案使用map代替mapValues。虽然这会产生相同的RDD元素,但我认为使用Spark RDD所需的“最小”功能非常重要,因为使用map代替{{mapValues实际上可以支付相当大的性能成本。 1}}没有意识到 - RDD上的map函数剥离了分区器(如果存在),mapValues没有。

如果您有RDD[(K, V)]并致电rdd.groupByKey(),则最终会得到RDD[(K, Array[V])]分区的K。如果您希望join使用另一个RDD K,那么您已经完成了大部分工作。

如果您在mapgroupByKey()之间添加join,Spark会重新调整该RDD。这真是太痛苦了! mapValues是安全的。

答案 1 :(得分:0)

在您的代码中, x._2.getList 会返回一个列表列表。使用如下的展平方法得到预期的结果:
my_rdd.map(x =>(x._1,x._2.getList.flatten))