在Spark中连接稀疏向量?

时间:2015-12-04 21:41:18

标签: scala apache-spark

假设您有两个稀疏矢量。举个例子:

val vec1 = Vectors.sparse(2, List(0), List(1)) // [1, 0]
val vec2 = Vectors.sparse(2, List(1), List(1)) // [0, 1]

我想连接这两个向量,以便结果等同于:

val vec3 = Vectors.sparse(4, List(0, 2), List(1, 1)) // [1, 0, 0, 1]

Spark有没有这样的便利方法呢?

3 个答案:

答案 0 :(得分:7)

如果您拥有DataFrame中的数据,那么VectorAssembler将是正确的选择。例如:

from pyspark.ml.feature import VectorAssembler

dataset = spark.createDataFrame(
    [(0, Vectors.sparse(10, {0: 0.6931, 5: 0.0, 7: 0.5754, 9: 0.2877}), Vectors.sparse(10, {3: 0.2877, 4: 0.6931, 5: 0.0, 6: 0.6931, 8: 0.6931}))],
["label", "userFeatures1", "userFeatures2"])

assembler = VectorAssembler(
    inputCols=["userFeatures1", "userFeatures2"],
    outputCol="features")

output = assembler.transform(dataset)
output.select("features", "label").show(truncate=False)

您将获得以下输出:

+---------------------------------------------------------------------------+-----+
|features                                                                   |label|
+---------------------------------------------------------------------------+-----+
|(20,[0,7,9,13,14,16,18],    [0.6931,0.5754,0.2877,0.2877,0.6931,0.6931,0.6931])|0|
+---------------------------------------------------------------------------+-----+

答案 1 :(得分:2)

我认为您在理解SparseVectors时遇到了一些问题。因此我会对它们做一点解释,第一个参数是特征的数量列|数据的维度,除了第二个参数中List的每个条目表示要素的位置,第三个List中的值表示该列的值,因此{{1}是局部敏感的,从我的观点来看,你的方法是错误的。

如果你更加注意你正在对两个具有相同维度的向量求和或组合,因此实际结果会有所不同,第一个参数告诉我们向量只有2维,所以SparseVectors和正确的表示形式为[1,0] + [0,1] => [1,1],而不是四维。

另一方面,如果每个向量具有两个不同的维度,并且您尝试将它们组合在一起并在更高维度的空间中表示它们,那么就说四个然后您的操作可能有效,但是这个功能SparseVector类不提供,你必须编写一个函数来执行此操作,例如(有点必要,但我接受建议):

Vectors.sparse(2, [0,1], [1,1])

答案 2 :(得分:2)

如果您的向量代表数据框的不同列,则可以使用VectorAssembler。只需要设置setInputcols(你的2个向量),Spark就会让你的愿望成真;)