[英]Dropping empty DataFrame partitions in Apache Spark
我嘗試根據 DataFrame 在分區列x
有N
(假設N=3
)個不同值的列重新分區 DataFrame ,例如:
val myDF = sc.parallelize(Seq(1,1,2,2,3,3)).toDF("x") // create dummy data
我想要實現的是通過x
重新分區myDF
而不產生空分區。 有沒有比這樣做更好的方法?
val numParts = myDF.select($"x").distinct().count.toInt
myDF.repartition(numParts,$"x")
(如果我不指定numParts
在repartiton
,我的大多數分區是空的(如repartition
創建200個分區)...)
我會考慮迭代df
分區並在其中獲取記錄計數以查找非空分區的解決方案。
val nonEmptyPart = sparkContext.longAccumulator("nonEmptyPart")
df.foreachPartition(partition =>
if (partition.length > 0) nonEmptyPart.add(1))
當我們得到非空分區 ( nonEmptyPart
) 時,我們可以使用coalesce()
清理空分區( 檢查 coalesce() 與 repartition() )。
val finalDf = df.coalesce(nonEmptyPart.value.toInt) //coalesce() accepts only Int type
它可能是也可能不是最好的,但是這個解決方案將避免改組,因為我們沒有使用repartition()
val df1 = sc.parallelize(Seq(1, 1, 2, 2, 3, 3)).toDF("x").repartition($"x")
val nonEmptyPart = sc.longAccumulator("nonEmptyPart")
df1.foreachPartition(partition =>
if (partition.length > 0) nonEmptyPart.add(1))
val finalDf = df1.coalesce(nonEmptyPart.value.toInt)
println(s"nonEmptyPart => ${nonEmptyPart.value.toInt}")
println(s"df.rdd.partitions.length => ${df1.rdd.partitions.length}")
println(s"finalDf.rdd.partitions.length => ${finalDf.rdd.partitions.length}")
輸出
nonEmptyPart => 3
df.rdd.partitions.length => 200
finalDf.rdd.partitions.length => 3
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.