Передача словаря в rdd в PySpark

Я просто получаю зависание Spark, и у меня есть функция, которая должна быть сопоставлена ​​с rdd, но использует глобальный словарь:

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_dict и my_list намного больше, а my_func сложнее.

Ответ 1

Вы забыли что-то важное о объектах Broadcast, у них есть свойство value, где хранятся данные.

Поэтому вам нужно изменить my_func на что-то вроде этого:

my_dict_bc = sc.broadcast(my_dict)

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