Convert a Spark Vector of features into an array
在spark处理数据的时候经常会有某个字段处理成Vector的情况,这样的字段在很多的数据固化组件中可能不能直接存储,这个时候需要我们变通一下,把得到的向量转变成Array或者字符串的格式,便于存储
Spark 3.0 增加了 vector_to_array 的UDF. 不需要自我实现了,直接调用即可。但是如果spark的版本较低,则需要自己实现转换逻辑。
时光机:https://github.com/apache/spark/pull/26910
提供两个代码示例,如果读者明确知道自己的数据是什么格式的向量,例如
import org.apache.spark.ml.linalg.DenseVector val toArr: Any => Array[Double] = _.asInstanceOf[DenseVector].toArray val toArrUdf = udf(toArr) val dataWithFeaturesArr = dataWithFeatures.withColumn("features_arr",toArrUdf('features))
但是如果读者不清楚自己的向量是哪个,那就尽可能去兼容一下,如下
import org.apache.spark.ml.linalg.{SparseVector, Vector} import org.apache.spark.mllib.linalg.{Vector => OldVector} private val vectorToArrayUdf = udf { vec: Any => vec match { case v: Vector => v.toArray case v: OldVector => v.toArray case v => throw new IllegalArgumentException( "function vector_to_array requires a non-null input argument and input type must be " + "`org.apache.spark.ml.linalg.Vector` or `org.apache.spark.mllib.linalg.Vector`, " + s"but got ${ if (v == null) "null" else v.getClass.getName }.") } }.asNonNullable()