在pyspark RDD中迭代用户定义的类对象

时间:2016-04-08 21:47:17

标签: python apache-spark ipython pyspark

我正在从csv读取数据并将该数据转换为python类对象。但是当我尝试使用用户定义的类对象迭代该rdd时,我会收到类似

的错误
_pickle.PicklingError: Can't pickle <class '__main__.User'>: attribute lookup User on __main__ failed

我在这里添加部分代码,

class User:
    def __init__(self, line):
        self.user_id = line[0]
        self.location = line[1]
        self.age = line[2]

def create_user(line):
    user = User(line)
    return user

def print_user(line):
    user = line
    print(user.user_id)

conf = (SparkConf().setMaster("local").setAppName("exercise_set_2").set("spark.executor.memory", "1g"))
sc = SparkContext(conf = conf)
users = sc.textFile("BX-Users.csv").map(lambda line: line.split(";"))  
users_objs = users.map(lambda entry: create_user(entry))
users_objs.map(lambda entry: print_user(entry))

对于上面的代码,我得到了像

这样的结果
PythonRDD[93] at RDD at PythonRDD.scala:43

CSV数据源网址(需要拉链提取):HERE

更新 更改代码以包含collect将再次导致错误,我仍然需要尝试使用Pickle。我之前从未尝试过那个,如果你有人有样品,我可以轻松地做到。

users_objs = users.map(lambda entry: create_user(entry)).collect()

1 个答案:

答案 0 :(得分:1)

使用时

def create_user(line):
    user = User(line)
    return user

直接在地图调用中,这意味着您的节点必须可以访问User类。通常这意味着它需要可序列化/可选择。节点如何使用该类,或知道它是什么(除非你有一个常见的NFS挂载或什么)?这就是你得到那个泡菜错误的原因。要使User类可选,请阅读:https://docs.python.org/2/library/pickle.html

此外,您没有在RDD上执行collect(),这就是您看到PythonRDD[93] at RDD at PythonRDD.scala:43的原因。它仍然只是一个RDD,你的数据在节点上。