如何在scala数据帧中将Array[Long]转换为Vector类型?

问题描述 投票:0回答:2

我有这样的数据框:

+------+-----+-------------------+--------------------+
|    Id|Label|          Timestamp|         Signal_list|
+------+-----+-------------------+--------------------+
|A05439|    1|2014-05-20 05:05:21|[-116, -123, -129...|
|A06392|    1|2013-12-27 04:12:33|[260, 314, 370, 4...|
|A08192|    1|2014-06-03 04:06:15|[334, 465, 628, 8...|
|A08219|    3|2013-12-31 03:12:41|[-114, -140, -157...|
|A02894|    2|2013-10-28 06:10:53|[109, 139, 170, 1...|

这个数据帧信号列表有 9k 个元素,我想将信号列表列转换为向量。我尝试了下面的 UDF :

import org.apache.spark.ml.linalg._

val convertUDF = udf((array : Seq[Long]) => {
  Vectors.dense(array.toArray)
})
val afWithVector = afLabel.select("*").withColumn("Signal_list", convertUDF($"Signal_list"))

但它给出了错误:

console>:39: error: overloaded method value dense with alternatives:
  (values: Array[Double])org.apache.spark.ml.linalg.Vector <and>
  (firstValue: Double,otherValues: Double*)org.apache.spark.ml.linalg.Vector
 cannot be applied to (Array[Long])
         Vectors.dense(array.toArray)

数据框架构:

|-- Id: string (nullable = true)
 |-- Label: integer (nullable = true)
 |-- Timestamp: string (nullable = true)
 |-- Signal_list: array (nullable = true)
 |    |-- element: long (containsNull = true)

我是 scala 的新手,使用 pyspark 的答案会更有帮助。

scala apache-spark dataframe vector apache-spark-sql
2个回答
4
投票

UDF
几乎是正确的。问题在于Spark中的向量只能使用双精度数,不接受长整型。在 Scala 中,更改将如下所示:

val convertUDF = udf((array : Seq[Long]) => {
  Vectors.dense(array.toArray.map(_.toDouble))
})

在Python中我相信它会看起来像这样:

udf(lambda vs: Vectors.dense([float(i) for i in vs]), VectorUDT())

0
投票

在这里提供 pyspark 答案。
如果您使用spark 3.1.0,您的问题可以通过使用简单地解决:

from pyspark.ml.functions import array_to_vector
dataframe= dataframe.withColumn(feature_name_old, array_to_vector(feature_name_new))
© www.soinside.com 2019 - 2024. All rights reserved.