从 Spark DataFrame 列中的数组获取最小值

nic*_*chy 4 scala apache-spark

我有一个带有数组的数据框。

val DF = Seq(
  ("123", "|1|2","3|3|4" ),
  ("124", "|3|2","|3|4" )
).toDF("id", "complete1", "complete2")
.select($"id", split($"complete1", "\\|").as("complete1"), split($"complete2", "\\|").as("complete2"))

|id           |complete1|complete2|
+-------------+---------+---------+
|          123| [, 1, 2]|[3, 3, 4]|
|          124| [, 3, 2]| [, 3, 4]|
+-------------+---------+---------+
Run Code Online (Sandbox Code Playgroud)

如何提取每个数组的最小值?

|id           |complete1|complete2|
+-------------+---------+---------+
|          123| 1       | 3       |
|          124| 2       | 3       |
+-------------+---------+---------+
Run Code Online (Sandbox Code Playgroud)

我尝试定义一个 UDF 来执行此操作,但出现错误。

def minArray(a:Array[String]) :String = a.filter(_.nonEmpty).min.mkString
val minArrayUDF = udf(minArray _)   
def getMinArray(df: DataFrame, i: Int): DataFrame = df.withColumn("complete" + i, minArrayUDF(df("complete" + i)))

val minDf = (1 to 2).foldLeft(DF){ case (df, i) => getMinArray(df, i)}

java.lang.ClassCastException: scala.collection.mutable.WrappedArray$ofRef cannot be cast to [Ljava.lang.String;
Run Code Online (Sandbox Code Playgroud)

Sem*_*oor 7

从 Spark 2.4 开始,您可以使用它array_min来查找数组中的最小值。要使用此函数,您首先必须将字符串数组转换为整数数组。转换还将通过将空字符串转换为值来处理它们null

DF.select($"id",
          array_min(expr("cast(complete1 as array<int>)")).as("complete1"),
          array_min(expr("cast(complete2 as array<int>)")).as("complete2"))
Run Code Online (Sandbox Code Playgroud)