为什么我不能在减少逻辑中引用键?

时间:2016-10-11 00:18:46

标签: python mapreduce pyspark

我希望underscores / combineByKey / reduceByKey中的逻辑依赖于当前正在操作的密钥。从方法签名我可以看出,传递给这些方法的唯一参数是组合/缩小/折叠的值。

使用一个简单的例子,我只有一个foldByKey元组的RDD,我想要的结果是由(int, int)键控的rdd,其中值是最接近键的tuple[0]

例如:

int

应减少到:

(1, 8)
(1, 3)
(1, -1)
(2, 4)
(2, 5)
(2, 2)
(3, 2)
(3, 4)

请注意,在比较(1, 3) (2, 2) (3, 2) (1, 3)时,我并不关心选择哪一个,因为它们的距离都相同。对于" 3"键。

我想象这样做的方式将是:

(1, -1)

rdd.reduceByKey(lambda key, v1, v2: v1 if abs(key - v1) < abs(key - v2) else v2) 函数只需要2个参数:要合并的两个值。似乎最简单的方法是在我的reducer中引用键来实现我的目标;这有可能吗?

如果我试试这个,我会收到错误:

reduce
  

TypeError :()需要3个参数(给定2个)

我并不是在寻找这个示例问题的解决方案。我想知道的是,有没有理由将密钥传递给rdd = sc.parallelize([(1, 8), (1, 3), (1, -1), (2, 4), (2, 5), (2, 2), (3, 2), (3, 4)]) rdd.reduceByKey(lambda key, v1, v2: v1 if abs(key - v1) < abs(key - v2) else v2).collect() 函数?我认为这是我缺少的map-reduce哲学的一些基本原则。

注意我可以通过插入一个映射步骤来解决我的例子,该步骤将每个值映射到一个元组,该元组由值和距键的距离组成:

reduceByKey

1 个答案:

答案 0 :(得分:0)

我认为没有强有力的理由不传递密钥 但是,我觉得reduceByKey API是针对常见用例设计的 - 计算每个键值的总和。到目前为止,我从未在值计算中需要键。但那只是我的意见。

您解决的问题似乎也是简单的聚合问题。 min()groupByKey可以找到答案。我知道你不是在寻找解决方案,但这就是我写作的方式。

from pyspark import SparkContext

sc = SparkContext()
rdd = sc.parallelize([(1, 8), (1, 3), (1, -1), (2, 4), (2, 5), (2, 2), (3, 2), (3, 4)])
reduced = rdd.groupByKey().map(lambda (k, v): (k, min(v, key=lambda e:abs(e-k))))
print(reduced.collectAsMap())

结果

{1: 3, 2: 2, 3: 2}