Pyspark中的SparseVector到DenseVector转换

时间:2015-09-08 11:37:59

标签: python numpy apache-spark pyspark

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

from pyspark.mllib.linalg import SparseVector, DenseVector

DenseVector(SparseVector(5, {4: 1.}))

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

  

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

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

  

回溯(最近一次呼叫最后一次):文件"",第1行,in      File" /usr/lib/spark/python/pyspark/mllib/linalg.py" ;, line   206,在 init 中       ar = np.array(ar,dtype = np.float64)File" /usr/lib/spark/python/pyspark/mllib/linalg.py" ;, line 673,in   的的GetItem       提高ValueError("索引%d超出范围。"%index)ValueError:索引5超出范围。

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

DenseVector(SparseVector(5, {0: 1.}))

我希望:

  

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

但得到:

  • Ubuntu的:
  

回溯(最近一次呼叫最后一次):文件"",第1行,in      文件   " /home/skander/spark-1.4.1-bin-hadoop2.6/python/pyspark/mllib/linalg.py" ;,   第206行,在 init 中       ar = np.array(ar,dtype = np.float64)File" /home/skander/spark-1.4.1-bin-hadoop2.6/python/pyspark/mllib/linalg.py",   第676行, getitem       row_ind = inds [insert_index] IndexError:index out of bounds

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

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

1 个答案:

答案 0 :(得分:8)

Spark 2.0.2 +

您应该能够迭代SparseVectors。请参阅:SPARK-17587

Spark< 2.0.2

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

  1. arbytes个对象(不可变的整数序列,范围为0< = x< 256
  2. 否则,我们只需致电np.array(ar, dtype=np.float64)
  3. SparseVector显然不是bytes对象,因此在将其传递给构造函数时,会使用object参数进行np.array调用。如果您选中numpy.array docs,就会知道object应该是

      

    数组,公开array interface的任何对象,__array__方法返回数组的对象,或任何(嵌套)序列。

    您可以检查SparseVector是否符合上述条件。它不是Python sequence type和:

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

    如果您想将SparseVector转换为DenseVector,您应该使用toArray方法:

    DenseVector(sv.toArray())
    

    修改

    我认为这种行为解释了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.