PySpark的reduceByKey没有按预期工作

时间:2015-10-10 22:32:38

标签: python apache-spark pyspark rdd reduce

我正在编写一个大型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])。相反,我得到以下输出:

[(0, [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 24, 36, 48, 60, 72, 84])] 

有人可以帮我理解为什么会产生这个输出吗?

作为附注,当我使用

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

我得到了预期的输出。

1 个答案:

答案 0 :(得分:1)

首先,您实际上希望groupByKey不是reduceByKey

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

有人可以帮我理解为什么会产生这个输出吗?

<{> reduceByKey assumes f associativemethod显然不是[1], [2], [3], [4] 。根据操作顺序,输出是不同的。假设你开始使用某个键的以下数据:

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

现在添加let添加一些括号:

  1. (([1, 2], [3]), [4])
  2. ([1, 2, 3], [4])
  3. [1, 2, 3, 4]
  4. (([1], ([2], [3])), [4])
  5. 并使用另一组括号

    1. (([1], [2, 3]), [4])
    2. ([1, 2], [4])
    3. [1, 2, 4]
    4. method = lambda x, y: x + y
    5. 当您按如下方式重写时:

      from operator import add
      method = add
      

      或只是

      reduce*

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

      一般来说,对于using System; using System.Windows.Forms; class MyPanel : Panel { public MyPanel() { this.DoubleBuffered = this.ResizeRedraw = true; } protected override void OnPaint(PaintEventArgs e) { e.Graphics.TranslateTransform(this.AutoScrollPosition.X, this.AutoScrollPosition.Y); base.OnPaint(e); } } 操作,您需要具有关联性和commutative的函数。