Spark SparseVector向下修剪零个元素



我知道Spark SparseVector中通常不应该有任何零元素,因为它由默认值(0.0)表示,但在我使用以下代码创建SparseVector的情况下:

In : Vectors.sparse(5, [0, 1, 3, 5], [0.0, 1, 2, 0.0])
Out: SparseVector(5, {0: 0.0, 1: 1.0, 3: 2.0, 5: 0.0})

然后我可以得到一个SparseVector,它包含零个元素。

我的问题是,我如何将可以用默认值表示的零元素从上面移除到下面的SparseVector,如下所示:

SparseVector(5, {1: 1.0, 3: 2.0})

此外,SparseVector中的零元素是否占用任何空间?或者它实际上也在SparseVector实现中由默认值表示?

例如:

from pyspark.mllib.linalg import Vectors, SparseVector, DenseVector
def drop_zeros(x):
    """
    >>> drop_zeros(DenseVector([1.0, 0.0]))
    SparseVector(2, {0: 1.0})
    >>> drop_zeros(SparseVector(3, {0: 0.0, 1: 2.0, 2: 0.0}))
    SparseVector(3, {1: 2.0})
    """
    if isinstance(x, SparseVector):
        return SparseVector(
            x.size, {i: v for i, v in zip(x.indices, x.values) if v})
    if isinstance(x, DenseVector):
        return SparseVector(
            len(x), {i: v for i, v in enumerate(x.array) if v})
    raise TypeError("Invalid type {0}".format(type(x)))
sparse_with_zeros = Vectors.sparse(5, [0, 1, 3, 5], [0.0, 1, 2, 0.0])
drop_zeros(sparse_with_zeros)
## SparseVector(5, {1: 1.0, 3: 2.0})
dense_with_zeros = DenseVector([1.0, 3.0, 0.0, 2.0, 0.0])
## SparseVector(5, {0: 1.0, 1: 3.0, 3: 2.0})

在Scala中,最简单的方法是使用toSparse方法:

import org.apache.spark.mllib.linalg.{Vectors, DenseVector, SparseVector}
val sparse_with_zeros = Vectors.sparse(3, Array(0, 1, 2), Array(0.0, 1.0, 0.0))
sparse_with_zeros.toSparse
// org.apache.spark.mllib.linalg.SparseVector = (3,[1],[1.0])

此外,稀疏向量中的零元素是否占用任何空间?或者它实际上也在SparseVector实现中由默认值表示?

若向量是用零索引显式创建的,那个么这些零元素占用空间。

相关内容

  • 没有找到相关文章

最新更新