Есть несколько способов получить доступ к элементу Spark VectorUDT с помощью udf , как здесь . Но иногда udf не допускается, например, в некоторых производственных средах. Единственный способ, который я понял, - это преобразовать вектор в строку, извлечь данные, а затем преобразовать обратно во float. Но есть несколько сложностей. Например, разреженный вектор отличается от плотного вектора в формате строки. Я получаю следующий код:
from pyspark.ml.linalg import Vectors
from pyspark.ml.feature import VectorSlicer
from pyspark.ml.feature import SQLTransformer
df = sc.parallelize([
(1, Vectors.dense([1, 2, 3])),
(2, Vectors.sparse(3, [1], [9]))
]).toDF(["id", "features"])
#slice a single member, it is necessary , or the string format of spark vector and dense vector are too different to be extracted.
vs = VectorSlicer(inputCol="features", outputCol="sliced", indices=[2]) #here select third member of the vector
df2=vs.transform(df)
sqlt=SQLTransformer(statement=r"""select *
,cast(sliced as string) sliced_str
,coalesce(cast(regexp_extract(cast(sliced as string),'.*\\[(.*)\\]', 1) as float),0) member
from __THIS__""")
sqlt.transform(df2).toPandas()
output
id features sliced sliced_str member
0 1 [1.0, 2.0, 3.0] [3.0] [3.0] 3.0
1 2 (0.0, 9.0, 0.0) (0.0) (1,[],[]) 0.0
Это довольно неуклюже. Есть ли лучший способ?