NameError: имя 'a cc' не определено в аккумуляторе pyspark - PullRequest
1 голос
/ 09 мая 2020

Тестовый аккумулятор в pyspark, но он пошел не так:

def test():
    conf = SparkConf().setAppName("test").setMaster("local[*]")
    sc = SparkContext(conf=conf).getOrCreate()
    rdds = sc.parallelize([Row(user="spark", item="book"), Row(user="spark", item="goods"),
                            Row(user="hadoop", item="book"), Row(user="python", item="duck")])

    acc = sc.accumulator(0)
    print("accumulator: {}".format(acc))

    def imap(row):
        global acc
        acc += 1
        return row

    rdds.map(imap).foreach(print)
    print(acc.value)

Ошибка:

...
return f(*args, **kwargs)
File "test_als1.py", line 205, in imap
acc += 1
NameError: name 'acc' is not defined

Но я установил acc как глобальную переменную, как мне написать код?

Ответы [ 2 ]

0 голосов
/ 09 мая 2020

Проблема в том, что imap ссылается на глобальную переменную, которая не существует (присвоение в test создает только локальную переменную в этой функции). Эта простая программа (без Spark) выдает ту же ошибку по той же причине:

def foo():
    blah = 1
    def bar():
        global blah
        print(blah)
    bar()


if __name__ == '__main__':
    foo()

Назначение acc на уровне модуля работает:

if __name__ == '__main__':
    conf = SparkConf().setAppName("test").setMaster("local[*]")
    sc = SparkContext(conf=conf).getOrCreate()
    rdds = sc.parallelize([Row(user="spark", item="book"), Row(user="spark", item="goods"),
                           Row(user="hadoop", item="book"), Row(user="python", item="duck")])

    acc = sc.accumulator(0)
    print("accumulator: {}".format(acc))

    def imap(row):
        global acc
        acc += 1
        return row

    rdds.map(imap).foreach(print)
    print(acc.value)

Добавление global acc оператор для test является альтернативой, если вам нужно сохранить функцию test.

0 голосов
/ 09 мая 2020

Просто удалите эту строку.

global acc

global используется для доступа к глобально объявленной переменной, но ваша переменная объявлена ​​внутри функции, и вы можете получить к ней прямой доступ внутри своей вложенной функции imap.

Дополнительный пример глобального посещения здесь .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...