使用以下约束重新分区数据框的最有效方法是什么?

时间:2016-06-17 12:27:14

标签: apache-spark dataframe time-series rdd

我有一个时间序列数据帧存储在一个分区

+-------------+------+----+-------+
|    TimeStamp|     X|   Y|      Z|
+-------------+------+----+-------+
|1448949705421|-35888|4969|3491754|
|1448949705423|-35081|2795|3489177|
|1448949705425|-35976|5830|3488618|
|1448949705426|-36927|4729|3491807|
|1448949705428|-36416|6246|3490364|
|1448949705429|-36073|7067|3491556|
|1448949705431|-38553|3714|3489545|
|1448949705433|-39008|3034|3490230|
|1448949705434|-35295|4005|3489426|
|1448949705436|-36397|5076|3490941|
+-------------+------+----+-------+

我想将这个数据帧重新划分为10个分区,这样第一个分区大约有前1/10行,第二个分区大约有第二个1/10行,依此类推。

我能想到的一种方式是:

var df = ???
// add index to df
val rdd = df.rdd.zipWithIndex().map(indexedRow =>
            Row.fromSeq(indexedRow._2.toLong +: indexedRow._1.toSeq))
val newstructure = StructType(Seq(StructField("rn", LongType, true)).++(df.schema.fields))
val dfWithIndex = sqlContext.createDataFrame(rdd, newstructure)

// create a group number using the index
val udfToInt = udf[Int, Double](_.toInt)
val dfWithGrp = dfWithIndex.withColumn("group", udfToInt($"rn" / (df.count / 10)))

// repartition by the "group" column
val partitionedDF = dfWithGrp.repartition(10, $"group")

我能想到的另一种方法是使用分区器:

//After creating a group number
val grpIndex = dfWithGrp.schema.fields.size - 1
val partitionedRDD = dfWithGrp.rdd.map(r => (r.getInt(grpIndex), r))
    .partitionBy(new HashPartitioner(10))
    .values

但它们似乎效率不高,因为我们需要先添加索引,然后使用索引创建一个组号。有没有办法在不添加额外的组列的情况下执行此操作?

0 个答案:

没有答案