我使用Window.sum
函数来获取RDD中值的总和,但是当我将DataFrame转换为RDD时,我发现结果只有一个分区。何时进行重新分区?
val rdd = sc.parallelize(List(1,3,2,4,5,6,7,8), 4)
val df = rdd.toDF("values").
withColumn("csum", sum(col("values")).over(Window.orderBy("values")))
df.show()
println(s"numPartitions ${df.rdd.getNumPartitions}")
// 1
//df is:
// +------+----+
// |values|csum|
// +------+----+
// | 1| 1|
// | 2| 3|
// | 3| 6|
// | 4| 10|
// | 5| 15|
// | 6| 21|
// | 7| 28|
// | 8| 36|
// +------+----+
我在Window中添加了partitionBy,但结果是错误,我该怎么办?这是我的更改代码:
val rdd=sc.parallelize(List(1,3,2,4,5,6,7,8),4)
val sqlContext = new SQLContext(m_sparkCtx)
import sqlContext.implicits._
val df = rdd.toDF("values").withColumn("csum", sum(col("values")).over(Window.partitionBy("values").orderBy("values")))
df.show()
println(s"numPartitions ${df.rdd.getNumPartitions}")
//1
//df is:
// +------+----+
// |values|csum|
// +------+----+
// | 1| 1|
// | 6| 6|
// | 3| 3|
// | 5| 5|
// | 4| 4|
// | 8| 8|
// | 7| 7|
// | 2| 2|
// +------+----+
答案 0 :(得分:0)
Window
函数有partitionBy
api,用于对dataframe
和orderBy
进行分组,以按升序或降序对分组行进行排序。
在您的第一个案例中,您尚未定义partitionBy
,因此所有值都被归为一个dataframe
以便进行排序,从而将数据混合到一个分区中。
但在第二种情况下,您partitionBy
本身已定义values
。因此,由于每个值都是不同的,因此每行被分组为单独的组。
第二种情况下的分区是200,因为当您没有定义分区并且发生随机播放时,这是spark
中定义的默认分区
要获得第二种情况与第一种情况相同的结果,您需要将dataframe
分组为第一种情况,即分组到一组。为此,您需要创建另一个具有常量值的column
并将该值用于partitionBy
。
答案 1 :(得分:0)
将列创建为
时
withColumn("csum", sum(col("values")).over(Window.orderBy("values")))
Window.orderBy("values")
正在排序列"值"的值在单个分区中,因为您还没有定义partitionBy()
方法来定义分区。
这会将partition
的数量从最初的4改为1.
在第二种情况下,分区为200,因为partitionBy()
方法使用200作为默认分区。如果您需要分区数为4,则可以使用repartition(4)
或coalesce(4)
希望你明白这一点!