scala - 如何将 Spark 数据帧列从 Array[Int] 转换为 linalg.Vector?

标签 scala apache-spark apache-spark-sql apache-spark-ml

我有一个数据框 df,如下所示:

+--------+--------------------+
| user_id|        is_following|
+--------+--------------------+
|       1|[2, 3, 4, 5, 6, 7]  |
|       2|[20, 30, 40, 50]    |
+--------+--------------------+

我可以确认它具有架构:

root
 |-- user_id: integer (nullable = true)
 |-- is_following: array (nullable = true)
 |    |-- element: integer (containsNull = true)

我想使用 Spark 的 ML 例程(例如 LDA)对此进行一些机器学习,需要我将 is_following 列转换为 linalg.Vector (不是Scala 向量)。当我尝试通过

执行此操作时
import org.apache.spark.ml.feature.VectorAssembler
import org.apache.spark.ml.linalg.Vectors

val assembler = new VectorAssembler().setInputCols(Array("is_following")).setOutputCol("features")
val output = assembler.transform(df)

然后我收到以下错误:

java.lang.IllegalArgumentException: Data type ArrayType(IntegerType,true) is not supported.

如果我的解释正确,我就会明白我需要将这里的类型从整数转换为其他类型。 (双数?字符串?)

我的问题是,将此数组转换为能够为 ML 管道正确矢量化的数组的最佳方法是什么?

编辑:如果有帮助,我不必以这种方式构建数据帧。我可以改为:

+--------+------------+
| user_id|is_following|
+--------+------------+
|       1|           2|
|       1|           3|
|       1|           4|
|       1|           5|
|       1|           6|
|       1|           7|
|       2|          20|
|     ...|         ...|
+--------+------------+

最佳答案

将数组转换为 linalg.Vector 并同时将整数转换为 double 的一个简单解决方案是使用 UDF

使用您的数据框:

val spark = SparkSession.builder.getOrCreate()
import spark.implicits._

val df = spark.createDataFrame(Seq((1, Array(2,3,4,5,6,7)), (2, Array(20,30,40,50))))
  .toDF("user_id", "is_following")

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

val df2 = df.withColumn("is_following", convertToVector($"is_following"))

spark.implicits._ 在此导入以允许使用 $col()' 可以代替使用。

打印df2数据框将给出想要的结果:

+-------+-------------------------+
|user_id|is_following             |
+-------+-------------------------+
|1      |[2.0,3.0,4.0,5.0,6.0,7.0]|
|2      |[20.0,30.0,40.0,50.0]    |
+-------+-------------------------+

架构:

root
 |-- user_id: integer (nullable = false)
 |-- is_following: vector (nullable = true)

关于scala - 如何将 Spark 数据帧列从 Array[Int] 转换为 linalg.Vector?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46797335/

相关文章:

scala - Play Framework 路由不区分大小写

scala - 如何从 Scala 中的类列表中提取唯一元素

apache-spark - 为什么 persist(StorageLevel.MEMORY_AND_DISK) 给出与 HBase 的 cache() 不同的结果?

hadoop - 批处理模式中的 livy 抛出错误 Error : Only local python files are supported: Parsed arguments

python - Spark 非确定性 Pandas UDF 会出现什么问题

pyspark.sql.functions.col 和 pyspark.sql.functions.lit 之间的 PySpark 区别

sql - 使用 Spark SQL 将一列拆分为多列

list - 如何在Scala中加入两个列表?

scala - Spark : NullPointerException when RDD isn't collected before map

android - 将数据从运行时存储转换为案例类