确保DF的每个分区对于一个列/一组列具有相同的值

时间:2019-01-05 18:32:24

标签: apache-spark

我有一个数据框,其中包含“月份”,“年”,“日”,“时间戳”,“ ....和其他列”列,这些数据帧是从按“年”,“月”划分的实木复合地板中读取的和“天”。 我需要对数据进行分区,以使每个分区的数据仅对应一个“年”,“月”,“天”组合。

我有一个数据框,其中包含“月份”,“年”,“日”,“时间戳”,“ ....和其他列”列,这些数据帧是从按“年”,“月”划分的实木复合地板中读取的和“天”。 我需要对数据进行分区,以使每个分区的数据仅对应一个“年”,“月”,“天”组合。

然后我将在sortWithinPartitions上运行timestamp,然后在每个分区中按顺序处理数据(即通过mapPartitions)。问题是列上的repartition不能确保分区中的行仅包含“月”,“年”和“天”的一种组合。 为了解决这个问题,我已经完成

df.repartition("year", "month", "day", MAX_INT)                                      
  .sortWithinPartitions($"timestamp")
  .rdd                                       
  .mapPartitions(sequential_processing_function)

很难轻松验证它是否按预期正常工作。

问题是-这样可以正常工作吗,即每个分区仅包含“年”,“月”,“天”的单个组合的数据。

这是我根据用户@ user6910411的评论尝试过的内容

val keyList = (df.select($"year", $"month", $"day")
                 .distinct()
                 .select(concat($"year", lit(" "),
                                $"month", lit(" "),
                                $"day").alias("partition_key"))
                .rdd
                .map(x => x.getString(0))
                .collect())
val keyIndexMap = collection.mutable.Map[String, Long]()
for (i <- keyList.indices) keyIndexMap(keyList(i)) = i
var keyIndexMapBC = sc.broadcast(keyIndexMap)

class ExactPartitioner[V]() extends Partitioner {
  def getPartition(key: Any): Int = {
    return keyIndexMapBC.value(key.asInstanceOf[String]).toInt
  }

  def numPartitions(): Int = {
      return keyIndexMapBC.value.size
  }
}
val df_partitioned =
    spark.createDataFrame(df,                                                        
        .select("year", "month", "day", "timestamp", "other_columns")                                                                                                                  
        .rdd.map(row => (row.getAs[String]("year") + " " +                                                                         
                         row.getAs[String]("month") + " " +                                                                          
                         row.getAs[String]("day"), row))
        .partitionBy(new ExactPartitioner).values,                                                       
        intermediate_data_schema)

有了这个df_partitioned.rdd.partitions.size,我得到了正确数量的分区。

我又如何验证一切是否正常以及是否按预期工作?

0 个答案:

没有答案