我尝试根据DataFrame在分区列(ListView) view.findViewById(android.R.id.list);
中具有N
(假设为N=3
)不同值的列重新分区DataFrame,例如:
x
我想要实现的是val myDF = sc.parallelize(Seq(1,1,2,2,3,3)).toDF("x") // create dummy data
重新分配myDF
而不产生空分区。有没有比这样做更好的方法?
x
(如果我没有在val numParts = myDF.select($"x").distinct().count.toInt
myDF.repartition(numParts,$"x")
中指定numParts
,我的大多数分区都是空的(因为repartiton
创建了200个分区)...)
答案 0 :(得分:5)
我想到迭代df
分区并在其中获取记录数来找到非空分区的解决方案。
val nonEmptyPart = sparkContext.longAccumulator("nonEmptyPart")
df.foreachPartition(partition =>
if (partition.length > 0) nonEmptyPart.add(1))
由于我们得到了非空分区(nonEmptyPart
),我们可以使用coalesce()
(check coalesce() vs reparation())来清空空分区。
val finalDf = df.coalesce(nonEmptyPart.value.toInt) //coalesce() accepts only Int type
它可能是也可能不是最好的,但是这个解决方案会避免改组,因为我们没有使用reparation()
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