0

クラスのオブジェクトのリストに対して flatMap() を実行すると、エラーが発生します。int、list などの通常の python データ型では問題なく動作しますが、リストにクラスのオブジェクトが含まれているとエラーが発生します。コード全体は次のとおりです。

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' です。このエラーを解決するにはどうすればよいですか?

私はpyspark 1.4.1を実行しているubuntuに取り組んでいます

4

1 に答える 1

4

あなたが得るエラーは、 とはまったく関係ありませんflatMapnodeメイン スクリプトでクラスを定義すると、ドライバーでアクセスできますが、ワーカーには配布されません。それを機能させるにnodeは、別のモジュール内に定義を配置し、それがワーカーに配布されるようにする必要があります。

  1. 定義付きの別のモジュールを作成しnode、それを呼び出しましょうnode.py
  2. nodeこのクラスをメイン スクリプト内にインポートします。

    from node import node
    
  3. モジュールがワーカーに配布されていることを確認します。

    sc.addPyFile("node.py")
    

これで、すべてが期待どおりに動作するはずです。

余談ですが:

  • PEP 8では、クラス名に CapWords を推奨しています。難しい要件ではありませんが、生活が楽になります
  • __repr__メソッドは、オブジェクトの文字列表現を返す必要があります。少なくともそれが であることを確認しますstringが、適切な表現はさらに優れています:

    def __repr__(self):
         return "node({0})".format(repr(self.value))
    
于 2015-09-26T00:27:36.773 に答える