PySpark的reduceByKey没有按预期工作

2024-10-06 14:20:45 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在编写一个大型PySpark程序,最近在RDD上使用reduceByKey时遇到了麻烦。我已经能够用一个简单的测试程序重现这个问题。代码是:

from pyspark import SparkConf, SparkContext

APP_NAME = 'Test App'

def main(sc):
    test = [(0, [i]) for i in xrange(100)]
    test = sc.parallelize(test)
    test = test.reduceByKey(method)
    print test.collect()

def method(x, y):
    x.append(y[0])
    return x

if __name__ == '__main__':
    # Configure Spark
    conf = SparkConf().setAppName(APP_NAME)
    conf = conf.setMaster('local[*]')
    sc = SparkContext(conf=conf)

    main(sc)

我希望输出是基于Spark文档的(0, [0,1,2,3,4,...,98,99])。相反,我得到以下输出:

^{pr2}$

有人能帮我理解为什么要生成这个输出吗?在

作为旁注,当我使用

def method(x, y):
    x = x + y
    return x

我得到了预期的输出。在


Tags: nametest程序appreturnmainconfdef
1条回答
网友
1楼 · 发布于 2024-10-06 14:20:45

首先,看起来你实际上想要groupByKey而不是reduceByKey

rdd = sc.parallelize([(0, i) for i in xrange(100)])
grouped = rdd.groupByKey()
k, vs = grouped.first()
assert len(list(vs)) == 100

Could someone please help me understand why this output is being generated?

reduceByKeyassumes即{}是associative,而你的{}显然不是。根据操作顺序,输出是不同的。假设您从某个密钥的以下数据开始:

^{pr2}$

现在添加一些括号:

  1. ((([1], [2]), [3]), [4])
  2. (([1, 2], [3]), [4])
  3. ([1, 2, 3], [4])
  4. [1, 2, 3, 4]

和另一组括号

  1. (([1], ([2], [3])), [4])
  2. (([1], [2, 3]), [4])
  3. ([1, 2], [4])
  4. [1, 2, 4]

当你重写如下:

method = lambda x, y: x + y

或者干脆

from operator import add
method = add

你得到了一个关联函数,它按预期工作。在

一般来说,对于reduce*操作,您需要既有关联又有commutative的函数。在

相关问题 更多 >