使用 spark java 获取列的每个值的特定百分比数据

Posted

技术标签:

【中文标题】使用 spark java 获取列的每个值的特定百分比数据【英文标题】:Get certain percentage data on each values of a column using spark java 【发布时间】:2020-01-03 00:09:04 【问题描述】:

我想从更大的数据集中选择 100 万条记录。数据集有一个名为“城市”的列。 100 万条记录应包含来自“城市 1”的 15% 记录、来自“城市 2”的 30% 记录、来自“城市 3”的“55%”记录。我可以使用如下限制来选择。但这不会是随机选择。

dataset.filter(col("city").equals("city1")).limit(.15* 1 million)

我可以使用示例函数。但我不想过滤每个城市并对其进行采样。

dataset.filter(col("city").equals("city1")).sample(false,percentage);

有没有更好的方法来使用 spark java 获取数据的随机样本百分比?

【问题讨论】:

你有几个城市? 【参考方案1】:

你好像在找org.apache.spark.sql.DataFrameStatFunctions.sampleBy()

dataset.stat().sampleBy("city", ImmutableMap.of("city1", 0.15, "city2", 0.3, "city3", 0.55)

【讨论】:

虽然它没有给出确切的百分比,但调整种子值会得到更接近的结果。谢谢 哦,抱歉,我没有注意到您希望整个样本正好是 1M 记录。在这种情况下,您应该将采样率计算为ratio = count(city='city1') / (1M * 0.15) 等。【参考方案2】:

您可以使用按城市分区并按随机列排序的窗口。然后你可以计算排名,然后只保留第一个排名。

假设您有一张地图cityMap,它将每个城市与您要保留的样本数量相关联。您可以根据数据计算它,也可以提前知道您想要什么。

我在 scala 中编写解决方案以确保它有效,但如果您熟悉 spark Java API,则转换为 Java 应该很简单。我尝试使用类似 java 的语法;)

// creating the window
val win = Window.partitionBy("city").orderBy("random")

// defining a UDF that decides what records to sample
val isSampled = udf((r : Long, city : String) => r <= cityMap(city))

val sampledData = df
    .withColumn("random", rand())
    .withColumn("rank", rank().over(win))
    .where(isSampled(col("rank"), col("city")))
    .drop("rank", "random")

【讨论】:

以上是关于使用 spark java 获取列的每个值的特定百分比数据的主要内容,如果未能解决你的问题,请参考以下文章

SQL:查询以获取特定列的值的最后更改

Django Query以获取特定列的所有不同值的计数[重复]

获取 SQL 中另一列的每个值的最常见值

Spark 仅获取具有一个或多个空值的列

Java-Spark:如何在循环中迭代时获取 Dataset<Row> 列的值并在 when().otherwise() 中使用它?

如何计算另一列中特定值的列的平均值?