2016-01-13 13 views
13

私はちょうどスパークのこつを得る午前、と私はrddにマップする必要があるの機能を持っていますが、グローバル辞書使用にRDDする辞書:上記放送PySpark

from pyspark import SparkContext 

sc = SparkContext('local[*]', 'pyspark') 

my_dict = {"a": 1, "b": 2, "c": 3, "d": 4} # at no point will be modified 
my_list = ["a", "d", "c", "b"] 

def my_func(letter): 
    return my_dict[letter] 

my_list_rdd = sc.parallelize(my_list) 

result = my_list_rdd.map(lambda x: my_func(x)).collect() 

print result 

が期待できます結果;しかし、私は本当にグローバル変数my_dictの私の使用について確認していません。辞書のコピーはすべてのパーティションで作成されているようです。そして、ちょうど私が探しています何それはbroadcastのように見えた

..右されて感じることはありません。しかし、私はそれを使用しよう:私は次のエラーを取得

my_dict_bc = sc.broadcast(my_dict) 

def my_func(letter): 
    return my_dict_bc[letter] 

TypeError: 'Broadcast' object has no attribute '__getitem__ 

をこれは私が辞書を放送することができないことを意味しているようです。

私の質問:グローバル辞書を使用する関数がある場合は、それをrddにマップする必要があります。それを行う正しい方法は何ですか?

私の例は非常に単純ですが、実際にはmy_dictmy_listははるかに大きく、my_funcはもっと複雑です。

答えて

15

Broadcastオブジェクトで重要なことを忘れた場合は、データが格納されているvalueというプロパティがあります。

したがって、あなたがこのような何かにmy_funcを変更する必要があります:私は見

my_dict_bc = sc.broadcast(my_dict) 

def my_func(letter): 
    return my_dict_bc.value[letter] 
+0

!だから私は 'それが正しく動作my_dict_bc.value'追加したとき。そして、「放送」は共有されているオブジェクトを扱うための標準的なアプローチですよね? – Akavall

+0

はい、それは良い習慣です、しかし、辞書があまり大きくない場合、その後、あなたは何の問題 –

+0

せずにグローバルオブジェクトを使用することができます理にかなっています。ありがとうございました。 – Akavall