使VectorAssembler始终选择DenseVector

时间:2018-07-13 04:03:31

标签: python pyspark

这是使用df.columns的数据帧的结构。

['LastName',
 'FirstName',
 'Stud. ID',
 '10 Relations',
 'Related to Politics',
 '3NF',
 'Documentation & Scripts',
 'SQL',
 'Data (CSV, etc.)',
 '20 Relations',
 'Google News',
 'Cheated',
 'Sum',
 'Delay Factor',
 'Grade (out of 2)']

我已使用

在pyspark中转换了此数据框
assembler = VectorAssembler(inputCols=['10 Relations',
 'Related to Politics',
 '3NF'],outputCol='features')

output = assembler.transform(df)。现在,它包含一些Row对象。这些对象具有这种架构(这是我运行output.printSchema()时得到的东西)

root
 |-- LastName: string (nullable = true)
 |-- FirstName: string (nullable = true)
 |-- Stud. ID: integer (nullable = true)
 |-- 10 Relations: integer (nullable = true)
 |-- Related to Politics: integer (nullable = true)
 |-- 3NF: integer (nullable = true)
 |-- Documentation & Scripts: integer (nullable = true)
 |-- SQL: integer (nullable = true)
 |-- Data (CSV, etc.): integer (nullable = true)
 |-- 20 Relations: integer (nullable = true)
 |-- Google News: integer (nullable = true)
 |-- Cheated: integer (nullable = true)
 |-- Sum: integer (nullable = true)
 |-- Delay Factor: double (nullable = true)
 |-- Grade (out of 2): double (nullable = true)
 |-- features: vector (nullable = true)

对于每一行,汇编器选择使特征向量为稀疏或密集(出于内存原因)。但这是一个大问题。因为我想使用转换后的数据来制作线性回归模型。因此,我正在寻找一种使VectorAssembler始终选择密集矢量的方法。

有什么主意吗?

注意:我已阅读this post。但问题在于,由于Row类是元组的子类,因此在创建Row对象后,我无法更改它。

1 个答案:

答案 0 :(得分:0)

稀疏和密集向量均继承自pyspark.ml.linalg.Vector。因此,两种向量类型都具有.toarray()方法。您可以使用简单的udf将它们转换为numpy数组,然后转换为Dense vetor。

from pyspark.ml.linalg import DenseVector, SparseVector, Vectors, VectorUDT
from pyspark.sql import functions as F
from pyspark.sql.types import *


v = Vectors.dense([1,3]) # dense vector
u = SparseVector(2, {}) # sparse vector

# toDense function converts both vector  type into Dense Vector
toDense = lambda v: Vectors.dense(v.toArray()) 
toDense(u), toDense(v)

结果:

DenseVector([0.0, 0.0]), DenseVector([1.0, 3.0])

然后您可以使用此功能创建udf。

df = sqlContext.createDataFrame([
    ((v,)), 
    ((u,))
   ], ['feature'])

toDense = lambda v: Vectors.dense(v.toArray())
toDenseUdf = F.udf(toDense, VectorUDT())
df.withColumn('feature', toDenseUdf('feature')).show()

结果:

+---------+
|  feature|
+---------+
|[1.0,3.0]|
|[0.0,0.0]|
+---------+

您在列中具有单个向量类型。