apache spark - vectorassembler - Como acessar o elemento de uma coluna VectorUDT em um Spark DataFrame?



spark mllib knn (1)

Eu tenho um dataframe df com uma coluna VectorUDT chamada features . Como obtenho um elemento da coluna, digamos primeiro elemento?

Eu tentei fazer o seguinte

from pyspark.sql.functions import udf
first_elem_udf = udf(lambda row: row.values[0])
df.select(first_elem_udf(df.features)).show()

mas eu recebo um net.razorvine.pickle.PickleException: expected zero arguments for construction of ClassDict(for numpy.dtype) . Mesmo erro se eu fizer first_elem_udf = first_elem_udf(lambda row: row.toArray()[0]) .

Eu também tentei explode() mas eu recebo um erro porque requer um tipo de matriz ou mapa.

Esta deve ser uma operação comum, eu acho.


Converter saída para float :

from pyspark.sql.types import DoubleType
from pyspark.sql.functions import lit, udf

def ith_(v, i):
    try:
        return float(v[i])
    except ValueError:
        return None

ith = udf(ith_, DoubleType())

Exemplo de uso:

from pyspark.ml.linalg import Vectors

df = sc.parallelize([
    (1, Vectors.dense([1, 2, 3])),
    (2, Vectors.sparse(3, [1], [9]))
]).toDF(["id", "features"])

df.select(ith("features", lit(1))).show()

## +-----------------+
## |ith_(features, 1)|
## +-----------------+
## |              2.0|
## |              9.0|
## +-----------------+

Explicação:

Os valores de saída precisam ser resserializados para objetos Java equivalentes. Se você quiser acessar values (cuidado com os SparseVectors ) você deve usar o método item :

v.values.item(0)

que retornam escalares padrão do Python. Da mesma forma, se você quiser acessar todos os valores como uma estrutura densa:

v.toArray().tolist()




apache-spark-ml