Pyspark中的SparseVector到DenseVector转换

Ska*_*der 3 python numpy apache-spark pyspark

在PySpark 1.4.1中将SparseVector转换为DenseVector时出现意外错误:

from pyspark.mllib.linalg import SparseVector, DenseVector

DenseVector(SparseVector(5, {4: 1.}))
Run Code Online (Sandbox Code Playgroud)

这在Ubuntu上正常运行,运行pyspark,返回:

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

这导致RedHat出错,运行pyspark,返回:

回溯(最近一次调用最后一次):文件"",第1行,在文件"/usr/lib/spark/python/pyspark/mllib/linalg.py",第206行,在init ar = np.array(ar,dtype) = np.float64)文件"/usr/lib/spark/python/pyspark/mllib/linalg.py",第673行,在 getitem中 引发ValueError("索引%d超出范围."%index)ValueError:Index 5 out边界


此外,在这两个平台上,评估以下内容也会导致错误:

DenseVector(SparseVector(5, {0: 1.}))
Run Code Online (Sandbox Code Playgroud)

我希望:

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

但得到:

  • Ubuntu的:

回溯(最近一次调用最后一次):文件"",第1行,在文件"/home/skander/spark-1.4.1-bin-hadoop2.6/python/pyspark/mllib/linalg.py",第206行,in INIT AR = np.array(AR,D型细胞= np.float64)文件"/home/skander/spark-1.4.1-bin-hadoop2.6/python/pyspark/mllib/linalg.py",线路676,在的GetItem row_ind = inds [insert_index] IndexError:索引超出范围

注意:此错误消息与前一个错误消息不同,尽管错误发生在同一个函数中(代码位于https://spark.apache.org/docs/latest/api/python/_modules/pyspark/mllib/linalg.html)

  • RedHat:相同的命令导致分段错误,这会导致Spark崩溃.

zer*_*323 8

Spark 2.0.2+

你应该能够迭代SparseVectors.见:SPARK-17587.

Spark <2.0.2

嗯,第一个案例非常有趣,但整体行为看起来并不像一个bug.如果你看一下DenseVector构造函数,它只考虑两种情况.

  1. ar是一个bytes对象(0 <= x <256范围内的不可变整数序列)
  2. 否则我们只是打电话 np.array(ar, dtype=np.float64)

SparseVector显然不是一个bytes对象所以当它传递给构造函数时,它被用作一个object参数进行np.array调用.如果你检查numpy.array文档,object应该知道

数组,公开数组接口的任何对象,__array__方法返回数组的对象,或任何(嵌套)序列.

您可以检查SparseVector是否符合上述条件.它不是Python 序列类型,并且:

>>> sv = SparseVector(5, {4: 1.})
>>> isinstance(sv, np.ndarray)
False
>>> hasattr(sv, "__array_interface__")
False
>>> hasattr(sv, "__array__")
False
>>> hasattr(sv, "__iter__")
False
Run Code Online (Sandbox Code Playgroud)

如果你想转换SparseVectorDenseVector你应该使用toArray方法:

DenseVector(sv.toArray())
Run Code Online (Sandbox Code Playgroud)

编辑:

我认为这种行为解释了为什么DenseVector(SparseVector(...))在某些情况下可能有效:

>>> [x for x in SparseVector(5, {0: 1.})]
[1.0]
>>> [x for x in SparseVector(5, {4: 1.})]
Traceback (most recent call last):
...
ValueError: Index 5 out of bounds.
Run Code Online (Sandbox Code Playgroud)