我知道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实现中由默认值表示?
若向量是用零索引显式创建的,那个么这些零元素占用空间。