Spark Dataframe-每天随机抽样记录

时间:2019-07-01 22:06:13

标签: apache-spark

我在Hive中有一些数据,其中每天有大约500k个唯一的customerId。数据跨越2个月,并在date上进行了分区。这是分布的样子-

+----------+---------------+
|      date|unique_visitors|
+----------+---------------+
|2019-01-01|        500,000|
|2019-01-02|        500,000|
|2019-01-03|        500,000|
|2019-01-04|        500,000|
|2019-01-05|        500,000|
|2019-01-06|        500,000|
|..........|         ..... |
|2019-02-27|        500,000|
|2019-02-28|        500,000|
+----------+---------------+

我想实现一个函数,该函数以N作为输入,并在输出表中每天提供很多记录。

例如,如果我将N设为250k,那么我希望250k在60天的所有数据中每天都随机采样唯一的客户ID,以便我可以维护输出表中每天受众规模的一致性。

因此输出表中的总记录为250k * 60。这是我的输出表的分布情况-

+----------+---------------+
|      date|unique_visitors|
+----------+---------------+
|2019-01-01|        250,000|
|2019-01-02|        250,000|
|2019-01-03|        250,000|
|2019-01-04|        250,000|
|2019-01-05|        250,000|
|2019-01-06|        250,000|
|..........|         ..... |
|2019-02-27|        250,000|
|2019-02-28|        250,000|
+----------+---------------+

如何使用Spark实现此目标?

1 个答案:

答案 0 :(得分:0)

我只使用窗口函数 partitionBy 按日期进行分区并按随机值对其进行排序。我们使用该窗口函数添加“排名”列,然后按小于您的“ n”值的排名进行过滤,然后删除“排名”列。

import org.apahce.spark.sql.functions._
import org.apache.spark.sql.expressions.Window
import spark.implicits._

val n = 250000
val w = Window.partitionBy($"date").orderBy(rand())
val res = df.withColumn("rank", rank().over(w)).filter($"rank" <= n).drop("rank")