在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])
但得到:
回溯(最近一次呼叫最后一次):文件"",第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处的代码)
答案 0 :(得分:8)
Spark 2.0.2 +
您应该能够迭代SparseVectors
。请参阅:SPARK-17587。
Spark< 2.0.2 强>
嗯,第一个案例非常有趣,但总体行为看起来并不像一个bug。如果你看看DenseVector
构造函数,它只考虑两个例。
ar
是bytes
个对象(不可变的整数序列,范围为0< = x< 256 )np.array(ar, dtype=np.float64)
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.