2016-12-02 47 views
1

我有一個惱人的問題使用jupyter筆記本與火花。如何用PySpark和Jupyter分配類

我需要定義內的筆記本電腦的自定義類,並用它來執行一些地圖操作

from pyspark import SparkContext 
from pyspark import SparkConf 
from pyspark import SQLContext 

conf = SparkConf().setMaster("spark://192.168.10.11:7077")\ 
       .setAppName("app_jupyter/")\ 
       .set("spark.cores.max", "10") 

sc = SparkContext(conf=conf) 

data = [1, 2, 3, 4, 5] 
distData = sc.parallelize(data) 

class demo(object): 
    def __init__(self, value): 
     self.test = value + 10 
     pass 

distData.map(lambda x : demo(x)).collect() 

它提供了以下錯誤:

PicklingError: Can't pickle : attribute lookup main.demo failed

我知道這個錯誤是關於,但我找不出解決辦法..

我試過了:

  1. 在筆記本外定義一個demo.py python文件。它的工作原理,但它是這樣一個醜陋的解決方案...
  2. 創建一個動態模塊like this,然後再導入之後......這給了同樣的錯誤

會有什麼解決辦法?...我想一切都在同類筆記本

它是可以改變的東西工作:

  1. 方式火花的作品,也許有些泡菜配置
  2. 東西代碼...使用一些靜態魔術方法

回答

1

這裏沒有可靠和優雅的解決方法,此行爲與Spark沒有特別的關係。 This is all about fundamental design of the Python pickle

pickle can save and restore class instances transparently, however the class definition must be importable and live in the same module as when the object was stored.

理論上你可以定義一個custom cell magic這將:

  • 寫細胞對模塊的內容。
  • 導入它。
  • 撥打SparkContext.addPyFile來分配模塊。
from IPython.core.magic import register_cell_magic 
import importlib 

@register_cell_magic 
def spark_class(line, cell): 
    module = line.strip() 
    f = "{0}.py".format(module) 

    with open(f, "w") as fw: 
     fw.write(cell) 

    globals()[module] = importlib.import_module(module) 
    sc.addPyFile(f) 
In [2]: %%spark_class foo 
    ...: class Foo(object): 
    ...:  def __init__(self, x): 
    ...:   self.x = x 
    ...:  def __repr__(self): 
    ...:   return "Foo({0})".format(self.x) 
    ...: 

In [3]: sc.parallelize([1, 2, 3]).map(lambda x: foo.Foo(x)).collect() 
Out[3]: [Foo(1), Foo(2), Foo(3)]  

,但它是一次性交易。一旦文件被標記爲分發,它就不能被更改或重新分發。此外,在遠程主機上重新導入導入存在問題。我可以考慮一些更復雜的計劃,但這只是比它的價值更麻煩。

相關問題