繁体   English   中英

应用分区后无法从RDD转换为DataFrame

[英]Unable to Convert to DataFrame from RDD after applying partitioning

我正在使用Spark 2.1.0

当我尝试在数据框上使用Window函数时

val winspec = Window.partitionBy("partition_column")
DF.withColumn("column", avg(DF("col_name")).over(winspec))

我的计划发生更改,并将以下几行添加到物理计划中,由于这一额外阶段,正在发生额外的改组,并且数据量巨大,这使我的查询变慢,并且运行数小时。

+- Window [avg(cast(someColumn#262 as double)) windowspecdefinition(partition_column#460, ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) AS someColumn#263], [partition_column#460]
   +- *Sort [partition_column#460 ASC NULLS FIRST], false, 0
      +- Exchange hashpartitioning(partition_column#460, 200)

我也将舞台视为MapInternalPartition,我认为它在内部已分区现在我不知道这是什么。 但是因为我这样想,我的100个任务花了30分钟以上,而99个任务在1-2分钟内完成,最后1个任务花了30分钟,使我的集群IDLE没有并行处理,这使我认为使用窗口功能时,数据已正确分区???

我试图通过将其转换为RDD来应用HashPartitioning ...因为我们无法在数据帧上应用Custom / HashPartitioner

所以,如果我这样做:

val myVal = DF.rdd.partitioner(new HashPartitioner(10000))

我得到的返回类型为ANY ,但我没有执行任何动作列表。

我检查了一下,发现在Window函数中发生分区的列包含所有NULL值

TL; DR

  1. 使用窗口功能时的随机播放并不是多余的 它是正确性所必需的,无法删除。
  2. 应用分区改组。
  3. 数据集无法重用RDD分区。 使用Dataset进行分区应使用repartition方法:

     df.repartition($"col_name") 
  4. 但由于2)不能帮到您

  5. 和这个:

     val myVal = DF.rdd.partitioner(new HashPartitioner(10000)) 

    不会返回Any 它不会编译,因为RDD没有partitioner方法,该方法RDD参数。

    正确的方法是partitionBy但不适用于RDD[Row] ,由于3),它无法为您提供帮助。

如果有足够的内存,您可以尝试

df.join(
  broadcast(df.groupBy("partition_column").agg(avg(DF("col_name"))),
  Seq("partition_column")
)

编辑

如果你想计算移动平均( avgWindow.partitionBy("partition_column")按组,不运行平均计算全球平均水平),那么你的运气了。

如果分区列只有NULLS ,则任务不会分配并且是完全顺序的。

要计算全局运行平均值,您可以尝试应用类似于此方法的逻辑,该方法如何使用Spark计算累计和

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM