scala - 迭代列Scala的元素
问题描述
我有一个由两个双精度数组组成的数据框。我想创建一个新列,它是将欧几里德距离函数应用于前两列的结果,即如果我有:
A B
(1,2) (1,3)
(2,3) (3,4)
创造:
A B C
(1,2) (1,3) 1
(2,3) (3,4) 1.4
我的数据架构是:
df.schema.foreach(println)
StructField(col1,ArrayType(DoubleType,false),false)
StructField(col2,ArrayType(DoubleType,false),true)
每当我调用这个距离函数时:
def distance(xs: Array[Double], ys: Array[Double]) = {
sqrt((xs zip ys).map { case (x,y) => pow(y - x, 2) }.sum)
}
我收到一个类型错误:
df.withColumn("distances" , distance($"col1",$"col2"))
<console>:68: error: type mismatch;
found : org.apache.spark.sql.ColumnName
required: Array[Double]
ids_with_predictions_centroids3.withColumn("distances" , distance($"col1",$"col2"))
我知道我必须遍历每一列的元素,但我无法在任何地方找到如何执行此操作的解释。我对 Scala 编程非常陌生。
解决方案
要在数据框上使用自定义函数,您需要将其定义为UDF
. 例如,可以这样做:
val distance = udf((xs: WrappedArray[Double], ys: WrappedArray[Double]) => {
math.sqrt((xs zip ys).map { case (x,y) => math.pow(y - x, 2) }.sum)
})
df.withColumn("C", distance($"A", $"B")).show()
请注意,此处需要使用WrappedArray
(或)。Seq
结果数据框:
+----------+----------+------------------+
| A| B| C|
+----------+----------+------------------+
|[1.0, 2.0]|[1.0, 3.0]| 1.0|
|[2.0, 3.0]|[3.0, 4.0]|1.4142135623730951|
+----------+----------+------------------+
推荐阅读
- android - Dart:尝试运行 .dart 文件时未找到 UI
- react-native - React Native 动画无法改变背景颜色
- javascript - 有人可以帮我做一个有效的计时器吗
- javascript - VSCode 的格式化程序,在冒号前放置一个空格
- php - 可以找到一个 PHP 类,但不能找到另一个
- c# - 如何在 C# 的计算器中添加十个结果的变化历史?
- node.js - 如何处理路线中缺少的参数?表达
- php - 仅使用 php 中的 prepare 语句更新特定字段
- c++ - 为什么 C++ 程序给我地址而不是 MxN 数组 Col-Wise Sum 中的值,但给我 NxN 数组中的值?
- python - 我如何让我的不和谐机器人在聊天中显示,比如“机器人正在打字”