2015-09-26 4 views
0

Я получаю сообщение об ошибке при запуске flatMap() в списке объектов класса. Он отлично работает для регулярных типов данных python, таких как int, list и т. Д., Но мне грозит ошибка, когда список содержит объекты моего класса. Вот полный код:flatMap over list of custom objects in pyspark

from pyspark import SparkContext 

sc = SparkContext("local","WordCountBySparkKeyword") 

def func(x): 
    if x==2: 
     return [2, 3, 4] 
    return [1] 

rdd = sc.parallelize([2]) 
rdd = rdd.flatMap(func) # rdd.collect() now has [2, 3, 4] 
rdd = rdd.flatMap(func) # rdd.collect() now has [2, 3, 4, 1, 1] 

print rdd.collect() # gives expected output 

# Class I'm defining 
class node(object): 
    def __init__(self, value): 
     self.value = value 

    # Representation, for printing node 
    def __repr__(self): 
     return self.value 


def foo(x): 
    if x.value==2: 
     return [node(2), node(3), node(4)] 
    return [node(1)] 

rdd = sc.parallelize([node(2)]) 
rdd = rdd.flatMap(foo) #marker 2 

print rdd.collect() # rdd.collect should contain nodes with values [2, 3, 4, 1, 1] 

Код работает отлично до отметки 1 (прокомментирован в коде). Проблема возникает после маркера 2. Специальное сообщение об ошибке, которое я получаю, это AttributeError: 'module' object has no attribute 'node' Как устранить эту ошибку?

Я работаю на Ubuntu, работает pyspark 1.4.1

ответ

3

Ошибка вы получаете не имеет никакого отношения к flatMap. Если вы определяете класс node в своем основном скрипте, он доступен на драйвере, но он не распространяется среди рабочих. Чтобы он работал, вы должны указать определение node внутри отдельного модуля и убедиться, что оно распространяется среди рабочих.

  1. Создать отдельный модуль с node определения, позволяет называть его node.py
  2. Импорт этот node класс внутри основного сценария:

    from node import node 
    
  3. Убедитесь, что модуль распространяется на работников:

    sc.addPyFile("node.py") 
    

Теперь все должно работать должным образом.

На стороне записки:

  • PEP 8 рекомендует CapWords для имен классов. Это не является жестким требованием, но облегчает жизнь.
  • __repr__ метод должен вернуть a string representation of an object. По крайней мере, убедитесь, что это string, но правильное представление даже лучше:

    def __repr__(self): 
        return "node({0})".format(repr(self.value))