Spark数据帧中多列计算的优化方式?

时间:2017-06-08 20:26:17

标签: scala apache-spark apache-spark-sql user-defined-functions

解决以下用例的优化或性能最佳方法是什么

考虑一个100万行和100列的数据框,我们感兴趣的是1列 - 消息。我需要根据匹配关键字在消息中的条件构建3个新列。

  • 消息:堆栈溢出对代码开发的贡献是 日复一日地增加
  • flag1关键词:堆栈,松弛
  • flag2关键字:twitter,facebook,whatsapp
  • flag3关键字:流量,运行,增加

预期输出:(message,flag1,flag2,flag3)堆栈溢出对代码开发的贡献日益增加,1,0,0

方法1

 val tempDF = df.withColumn("flag1",computeFlag(col("message"))).withColumn("flag2",computeFlag(col("message"))).withColumn("flag3",computeFlag(col("message")))

方法2

 val tempDF = df.withColumn("flagValues",computeMultipleFlags(col("message"))).withColumn("_tmp", split($"flagValues","#")).select($"message",$"_tmp".getItem(0).as("flag1"),$"_tmp".getItem(1).as("commercial"),$"_tmp".getItem(2).as("flag2"),$"_tmp".getItem(3).as("flag3")).drop("_tmp")

UDF:computeFlag根据相应关键字列表的完全匹配返回1或0

UDF:computeMultipleFlags根据flag1,flag 2和flag 3的相应关键字的完全匹配返回#dullited结果1或0:示例1#0#0

我已经解决了使用这两种方法但看到/感觉方法2表现更好。请指教。

  • 默认情况下,Spark数据帧是并行化的,但这种情况如何 方法1.将计算flag1,flag2,flag3列 平行还是顺序?

  • Spark数据框会自动并行处理我的输入列 "消息" :多列的多个线程对列
    计算?

1 个答案:

答案 0 :(得分:0)

在这两种情况下,您都使用了\1个函数,这需要udf columnserialization,这会在处理过程中花费宝贵的时间。

在你的第一个案例中,你使用deserialization调用了相同的udf三次,这意味着每个标志生成都会发生三次序列化和反序列化

在第二种情况下,您只定义了一个withColumn函数。因此,与第一个相比,运行速度更快,效率更高。并且您使用了udf函数,这是一个好兆头。

split本质上是分布式的,因此每个函数调用在每个Dataframe中并行执行,但每个函数将按顺序执行,即数据并行化,但函数/任务仍然是顺序的

我希望解释清楚

使用Spark functions提供了一个更好的解决方案,它不需要像executors情况那样需要额外的序列化和反序列化。您可以使用以下解决方案。

udf