我有一个数据框,其中包含“月份”,“年”,“日”,“时间戳”,“ ....和其他列”列,这些数据帧是从按“年”,“月”划分的实木复合地板中读取的和“天”。 我需要对数据进行分区,以使每个分区的数据仅对应一个“年”,“月”,“天”组合。
我有一个数据框,其中包含“月份”,“年”,“日”,“时间戳”,“ ....和其他列”列,这些数据帧是从按“年”,“月”划分的实木复合地板中读取的和“天”。 我需要对数据进行分区,以使每个分区的数据仅对应一个“年”,“月”,“天”组合。
然后我将在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
,我得到了正确数量的分区。
我又如何验证一切是否正常以及是否按预期工作?