我有一个特殊的情况,我需要从DenseVector转到稀疏向量列。
我正在尝试实施在这里找到的SMOTE技术:https://github.com/Angkirat/Smote-for-Spark/blob/master/PythonCode.py
但是在第44行,由于错误,我不得不将其从min_Array[neigh][0] - min_Array[i][0]
更改为DenseVector(min_Array[neigh][0]) - DenseVector(min_Array[i][0])
。
一旦有了DenseVector列,就需要将其转换回SparseVector列以合并我的数据。
我尝试了以下方法:
df = sc.parallelize([
(1, DenseVector([0.0, 1.0, 1.0, 2.0, 1.0, 3.0, 0.0, 0.0, 0.0, 0.0])),
(2, DenseVector([0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 100.0])),
(3, DenseVector([0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0])),
]).toDF(["row_num", "features"])
list_to_vector_udf = udf(lambda l: Vectors.sparse(l), VectorUDT())
df = df.withColumn('features', list_to_vector_udf(df["features"]))
“ int()参数必须是字符串,类似字节的对象或数字,而不是'DenseVector'
assembler = VectorAssembler(inputCols=['features'],outputCol='features')
df = assembler.transform(df)
“不支持列特征的数据类型struct
答案 0 :(得分:0)
将密集向量转换为稀疏向量通常没有太大意义,因为密集向量已经占用了内存。如果确实需要执行此操作,请查看稀疏矢量API,它可以接受对列表(索引,值),或者需要将非零索引和值直接传递给构造函数。类似于以下内容:
from pyspark.ml.linalg import Vectors, VectorUDT
from pyspark.ml.linalg import DenseVector
df = sc.parallelize([
(1, DenseVector([0.0, 1.0, 1.0, 2.0, 1.0, 3.0, 0.0, 0.0, 0.0, 0.0])),
(2, DenseVector([0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 100.0])),
(3, DenseVector([0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0])),
]).toDF(["row_num", "features"])
def to_sparse(dense_vector):
size = len(dense_vector)
pairs = [(i, v) for i, v in enumerate(dense_vector.values.tolist()) if v != 0]
return Vectors.sparse(size, pairs)
dense_to_sparse_udf = udf(to_sparse, VectorUDT())
df = df.withColumn('features', dense_to_sparse_udf(df["features"]))
df.show()
+-------+--------------------+
|row_num| features|
+-------+--------------------+
| 1|(10,[1,2,3,4,5],[...|
| 2| (10,[9],[100.0])|
| 3| (10,[1],[1.0])|
+-------+--------------------+