如何规范化数据框中的数组列

时间:2017-10-01 14:13:59

标签: apache-spark dataframe spark-dataframe

我使用的是火花2.2。我想规范化固定大小数组中的每个值。

输入

{"values": [1,2,3,4]}

输出

{"values": [0.25, 0.5, 0.75, 1] }

目前,我正在使用 udf

val f = udf { (l: Seq[Double]) =>
  val max = l.max
  l.map(_ / max)
}

有没有办法避免使用udf(以及相关的性能损失)。

2 个答案:

答案 0 :(得分:2)

让我们说每个数组中的记录数是n

val n: Int

然后

 import org.apache.spark.sql.functions._


df
  .withColumn("max", greatest((0 until n).map(i => col("value")(i)): _*))
  .withColumn("values", array((0 until n).map(i => col("value")(i) / col("max")): _*))

答案 1 :(得分:0)

我已经提出了我的udf的优化版本,它执行就地更新。

  val optimizedNormalizeUdf = udf { (l: mutable.WrappedArray[Double]) =>
    val max = l.max
    (0 until n).foreach(i => l.update(i, l(i) / max))
    l
  }

我已经编写了一个基准来检查user8838736提出的解决方案的性能。结果如下。

[info] Benchmark                         Mode  Cnt    Score    Error  Units
[info] NormalizeBenchmark.builtin        avgt   10  140,293 ± 10,805  ms/op
[info] NormalizeBenchmark.udf_naive      avgt   10  104,708 ±  7,421  ms/op
[info] NormalizeBenchmark.udf_optimized  avgt   10   99,492 ±  7,829  ms/op

结论:在这种情况下, udf 是性能最佳的解决方案。

PS:对于那些感兴趣的人,基准的源代码在这里:https://github.com/YannMoisan/spark-jmh