如何使用 scala 从整数列表计算 ApproxQuanitiles 到 Spark DataFrame 列

How to calculate the ApproxQuanitiles from list of Integers into Spark DataFrame column using scala

我有一个 spark DataFrame,其中有一列包含多个长度不同的整数数组。我将需要创建一个新列来查找其中每一个的分位数。 这是输入数据框:

+---------+------------------------+
|Comm     |List_Nb_total_operations|
+---------+------------------------+
|    comm1|         [1, 1, 2, 3, 4]|
|    comm4|                  [2, 2]|
|    comm3|                  [2, 2]|
|    comm0| [1, 1, 1, 2, 2, 2, 3,3]|
|    comm2|         [1, 1, 1, 2, 3]|
+---------+------------------------+

这是想要的结果:

+---------+------------------------+----+----+
|Comm     |List_Nb_total_operations|QT25|QT75|
+---------+------------------------+----+----+
|    comm1|         [1, 1, 2, 3, 4]|   1|   3|
|    comm4|                  [2, 2]|   2|   2|
|    comm3|                  [2, 2]|   2|   2|
|    comm0| [1, 1, 1, 2, 2, 2, 3,3]|   1|   3|
|    comm2|         [1, 1, 1, 2, 3]|   1|   2|
+---------+------------------------+----+----+

您要使用的函数是percentile_approx(自 Spark 3.1 起):

val df = Seq(
  ("comm1", Seq(1,1,2,3,4)),
  ("comm4", Seq(2,2)),
  ("comm3", Seq(2,2)),
  ("comm0", Seq(1,1,1,2,2,2,3,3)),
  ("comm2", Seq(1,1,1,2,3))
).toDF("Comm", "ops")

val dfQ = df.select(
  col("Comm"),
  explode(col("ops")) as "ops")
  .groupBy("Comm")
  .agg(
    percentile_approx($"ops", lit(0.25), lit(100)) as "q25",
    percentile_approx($"ops", lit(0.75), lit(100)) as "q75"
  )

val dfWithQ = df.join(dfQ, Seq("Comm"))

documentation 有更多关于调整参数以提高准确性的信息。

感谢您的帮助。我找到了另一个对我的情况非常有效的解决方案:

import org.apache.spark.sql.functions._
import org.apache.spark.sql.Column
import org.apache.spark.sql.catalyst.expressions.aggregate.ApproximatePercentile

def percentile_approxx(col: Column, percentage: Column, accuracy: Column): Column = {
  val expr = new ApproximatePercentile(
      col.expr,  percentage.expr, accuracy.expr
  ).toAggregateExpression
  new Column(expr)
}
val perc_df = df.groupBy("Comm").agg(percentile_approxx(col("ops"), lit(0.75), lit(100)))