【问题标题】:How does Apache-Spark work with methods inside a classApache-Spark 如何使用类中的方法
【发布时间】:2015-09-25 13:39:18
【问题描述】:

我现在正在学习 Apache-Spark。仔细阅读 Spark 教程后,我了解了如何将 Python 函数传递给 Apache-Spark 来处理 RDD 数据集。但是现在我仍然不知道 Apache-Spark 如何与类中的方法一起工作。例如,我的代码如下:

import numpy as np
import copy
from pyspark import SparkConf, SparkContext

class A():
    def __init__(self, n):
        self.num = n

class B(A):
    ### Copy the item of class A to B.
    def __init__(self, A):
        self.num = copy.deepcopy(A.num)

    ### Print out the item of B
    def display(self, s):
        print s.num
        return s

def main():
    ### Locally run an application "test" using Spark.
    conf = SparkConf().setAppName("test").setMaster("local[2]")

    ### Setup the Spark configuration.
    sc = SparkContext(conf = conf)

    ### "data" is a list to store a list of instances of class A. 
    data = []
    for i in np.arange(5):
        x = A(i)
        data.append(x)

    ### "lines" separate "data" in Spark.  
    lines = sc.parallelize(data)

    ### Parallelly creates a list of instances of class B using
    ### Spark "map".
    temp = lines.map(B)

    ### Now I got the error when it runs the following code:
    ### NameError: global name 'display' is not defined.
    temp1 = temp.map(display)

if __name__ == "__main__":
    main()

实际上,我使用上面的代码使用temp = lines.map(B) 并行生成了class B 的实例列表。之后,我做了temp1 = temp.map(display),因为我想并行打印出class B 实例列表中的每个项目。但是现在出现了错误:NameError: global name 'display' is not defined. 我想知道如果我仍然使用 Apache-Spark 并行计算,我该如何解决这个错误。如果有人帮助我,我真的很感激。

【问题讨论】:

  • 1. display 是一个方法,所以你想要的是lambda x: x.display()。 2. 我已经提到过 - 如果您对副作用感兴趣,使用 foreach 是惯用的。 3. 我已经提到的另一件事是打印不会像您期望的那样工作。
  • 感谢您的精彩回答!!!现在我想知道为什么打印不能像你在这里提到的那样工作。
  • 另外,当我尝试 temp1 = temp.foreach(lambda x: x.display()) 时,它会显示一个新错误:AttributeError: 'module' object has no attribute 'A'。我该如何解决这个问题?非常感谢您的帮助!
  • 好吧,print 不会因为您看到上述错误的原因或多或少相同。我在answer for your previous question 中对其进行了概述。所有涉及 RDD 操作的事情都发生在工作节点上。这意味着 print 的输出到那里而不是驱动程序。如果你想使用类,它也必须运送给工人。一种方法是创建一个模块。详情请见here
  • 谢谢!由于这段代码存放在/mydir/test.py中,我把sc = SparkContext(conf = conf)改成了sc = SparkContext(conf = conf, ['/mydir/test.py']),我也把temp1 = temp.map(display)改成了temp1 = temp.map(lambda x: x.display()).reduce(lambda x: x),但还是报错:'module' object has no attribute 'A'。你能帮我找出原因吗?

标签: python class methods apache-spark


【解决方案1】:

结构

.
├── ab.py
└── main.py

main.py

import numpy as np
from pyspark import SparkConf, SparkContext
import os
from ab import A, B

def main():
    ### Locally run an application "test" using Spark.
    conf = SparkConf().setAppName("test").setMaster("local[2]")

    ### Setup the Spark configuration.
    sc = SparkContext(
            conf = conf, pyFiles=[
               os.path.join(os.path.abspath(os.path.dirname(__file__)), 'ab.py')]
    ) 

    data = []
    for i in np.arange(5):
        x = A(i)
        data.append(x)

    lines = sc.parallelize(data)
    temp = lines.map(B)

    temp.foreach(lambda x: x.display()) 

if __name__ == "__main__":
    main()

ab.py

import copy

class A():
    def __init__(self, n):
        self.num = n

class B(A):
    ### Copy the item of class A to B.
    def __init__(self, A):
        self.num = copy.deepcopy(A.num)

    ### Print out the item of B
    def display(self):
        print self.num

评论:

  • 再一次 - 打印是个坏主意。忽略 Spark 架构很有可能会成为您程序的瓶颈。
  • 如果您需要诊断输出,请考虑记录或收集样本并在本地检查:for x in rdd.sample(False, 0.001).collect(): x.display()
  • 对于副作用使用foreach 而不是map
  • 我修改了display 方法。在这种情况下,我不确定 s 应该是什么

【讨论】:

  • 精彩的答案!!!现在它完美地工作了。另外,我想我仔细阅读了有关此 (spark.apache.org/docs/latest/index.html) 的 Spark 教程,但我仍然对架构以及函数的用法感到困惑。如果可能的话,请您推荐书籍或其他教程吗?我真的很感激!!!
  • 一般来说,建议在 SO 上是题外话,但对于初学者,您可以尝试 @holden 共同撰写的 AMP CampLearning Spark
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-05-21
  • 2015-09-14
  • 1970-01-01
  • 2015-04-04
  • 2015-06-16
  • 2015-05-21
相关资源
最近更新 更多