![](/img/trans.png)
[英]Using a method from a Python class as a PySpark user-defined function
[英]Iterating user-defined class objects inside a pyspark RDD
我正在从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数据源URL(需要zip提取): 此处
更新:将代码更改为包括收集将再次导致错误,我仍然必须尝试使用Pickle。 我以前从未尝试过这样做,如果您有样品,我可以轻松完成。
users_objs = users.map(lambda entry: create_user(entry)).collect()
使用时
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
看到PythonRDD[93] at RDD at PythonRDD.scala:43
。 它仍然只是一个RDD,您的数据在节点上。
好的,找到了解释。 将类存储在单独的文件中将使这些类自动可腌制 。 因此,我将User类存储在user.py中,并将以下导入添加到我的代码中。
from user import User
User.py的内容
class User:
def __init__(self, line):
self.user_id = line[0]
self.location = line[1]
self.age = line[2]
正如前面的答案中提到的,我可以在创建的User对象上收集用户(RDD方法)。 因此,以下代码将根据需要打印所有用户ID。
for user_obj in users.map(lambda entry: create_user(entry)).collect():
print_user(user_obj)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.