我编写了一个在python中实现分类器的类。我想使用Apache Spark来使用此分类器并行化大量数据点的分类。
然而,当我执行以下操作时:
import BoTree
bo_tree = BoTree.train(data)
rdd = sc.parallelize(keyed_training_points) #create rdd of 10 (integer, (float, float) tuples
rdd = rdd.mapValues(lambda point, bt = bo_tree: bt.classify(point[0], point[1]))
out = rdd.collect()
Spark因错误而失败(我认为只是相关的一点):
File "/root/spark/python/pyspark/worker.py", line 90, in main
command = pickleSer.loads(command.value)
File "/root/spark/python/pyspark/serializers.py", line 405, in loads
return cPickle.loads(obj)
ImportError: No module named BoroughTree
任何人都可以帮助我吗?有点绝望......
由于
答案 0 :(得分:15)
可能最简单的解决方案是在创建pyFiles
时使用SparkContext
参数
from pyspark import SparkContext
sc = SparkContext(master, app_name, pyFiles=['/path/to/BoTree.py'])
放置在那里的每个文件都会发送给工作人员并添加到PYTHONPATH
。
如果您在交互模式下工作,则必须先使用sc.stop()
停止现有上下文,然后才能创建新的上下文。
还要确保Spark worker实际上使用的是Anaconda发行版而不是默认的Python解释器。根据您的描述,这很可能是问题所在。要设置PYSPARK_PYTHON
,您可以使用conf/spark-env.sh
个文件。
另一方面,将文件复制到lib
是一个相当混乱的解决方案。如果你想避免使用pyFiles
推送文件,我建议你创建普通的Python包或Conda包以及正确的安装。通过这种方式,您可以轻松跟踪已安装的内容,删除不必要的软件包并避免一些难以调试的问题。
答案 1 :(得分:11)
获取SparkContext后,也可以使用addPyFile
随后将模块发送给每个工作人员。
sc.addPyFile('/path/to/BoTree.py')