【问题标题】:How to groupByKey a RDD, with DenseVector as key, in Spark?如何在 Spark 中以 DenseVector 为键对 RDD 进行分组?
【发布时间】:2015-07-16 08:43:55
【问题描述】:

我创建了一个 RDD,每个成员都是一个键值对,键是 DenseVector,值是 int。例如

[(DenseVector([3,4]),10),  (DenseVector([3,4]),20)]

现在我想通过键 k1: DenseVector([3,4]) 进行分组。我希望该行为将键k1 的所有值分组,即1020。但我得到的结果是

[(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())

【问题讨论】:

  • 你在做什么代码?描述你做了什么你得到了结果,这似乎很奇怪!
  • 我刚刚添加了代码。
  • 你的做法是对的!我认为可能有问题

标签: python apache-spark pyspark apache-spark-mllib


【解决方案1】:

嗯,这是一个棘手的问题,简短的回答是你不能。要了解为什么您必须深入研究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'

DenseVectorobject 继承__hash__ 方法,它只是基于id(给定实例的内存地址):

>>> id(d1) / 16 == hash(d1)
True

不幸的是,这意味着两个具有相同内容的DenseVectors具有不同的哈希值:

>>> dv2 = DenseVector([3.0, 4.0])
>>> hash(dv1) == hash(dv2)
False

你能做什么?最简单的方法是使用提供一致的hash 实现的不可变数据结构,例如元组:

rdd.groupBy(lambda (k, v): tuple(k))

注意:在实践中,使用数组作为键很可能是个坏主意。对于大量元素,散列过程可能非常昂贵而无法使用。不过,如果你真的需要这样的东西,Scala 似乎工作得很好:

import org.apache.spark.mllib.linalg.Vectors

val rdd = sc.parallelize(
    (Vectors.dense(3, 4), 10) :: (Vectors.dense(3, 4), 20) :: Nil)
rdd.groupByKey.collect

【讨论】:

  • 这是一个完美的答案!
  • 谢谢!正是我所缺少的!
  • 谢谢。我在 JIRA 上创建了一个问题:issues.apache.org/jira/browse/SPARK-9098
  • 它在 Scala 上运行得非常好,这就是为什么我对结果感到惊讶。
  • 有趣的是 Scala 使用了同样可变的微风向量,并且可以使用来自toArray:val y = Vectors.dense(1, 2, 3); val h1 = y.hashCode; y.toArray(0) = -1; h1 == y.hashCode 的输出来改变向量。好吧,我猜,当涉及到这样的事情时,Python 更加固执己见。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-07-13
  • 2015-12-26
  • 2021-06-04
  • 1970-01-01
  • 2016-12-13
  • 2017-06-15
相关资源
最近更新 更多