我创建了一个RDD,每个成员都是一个键值对,键为DenseVector
,值为int
。例如
[(DenseVector([3,4]),10), (DenseVector([3,4]),20)]
现在我想按键k1
分组:DenseVector([3,4])
。我希望该行为能够对k1
和10
的密钥20
的所有值进行分组。但我得到的结果是
[(DenseVector([3,4]), 10), (DenseVector([3,4]), 20)]
而不是
[(DenseVector([3,4]), [10,20])]
如果我错过了什么,请告诉我。
相同的代码是:
#simplified version of code
#rdd1 is an rdd containing [(DenseVector([3,4]),10), (DenseVector([3,4]),20)]
rdd1.groupByKey().map(lambda x : (x[0], list(x[1])))
print(rdd1.collect())
答案 0 :(得分:3)
嗯,这是一个棘手的问题,简短的回答是你不能。要了解为什么您必须深入了解DenseVector
实施。 DenseVector
只是NumPy float64
ndarray
>>> dv1 = DenseVector([3.0, 4.0])
>>> type(dv1.array)
<type 'numpy.ndarray'>
>>> dv1.array.dtype
dtype('float64')
由于NumPy ndarrays
与DenseVector
不同,因此不可能以有意义的方式进行哈希处理,尽管有趣的是提供__hash__
方法。有一个有趣的问题涉及这个问题(参见:numpy ndarray hashability)。
>>> dv1.array.__hash__() is None
False
>>> hash(dv1.array)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: unhashable type: 'numpy.ndarray'
DenseVector
继承__hash__
的{{1}}方法,它只是基于object
(给定实例的内存地址):
id
不幸的是,这意味着具有相同内容的两个>>> id(d1) / 16 == hash(d1)
True
具有不同的哈希值:
DenseVectors
你能做什么?最简单的方法是使用不可变的数据结构,它提供一致的>>> dv2 = DenseVector([3.0, 4.0])
>>> hash(dv1) == hash(dv2)
False
实现,例如元组:
hash
注意:实际上,使用数组作为键很可能是一个坏主意。使用大量元素进行散列处理可能会非常昂贵而有用。不过,如果你真的需要这样的东西,Scala似乎工作得很好:
rdd.groupBy(lambda (k, v): tuple(k))