pyspark getattr()行为

时间:2015-03-24 19:29:33

标签: apache-spark pyspark

注意到PySpark的一些奇怪行为,会很感激任何见解。

假设我有一个由简单元素组成的RDD

from collections import namedtuple
Animal = namedtuple('Animal', ('name','age'))
a = Animal('jeff',3)
b = Animal('mike',5)
c = Animal('cathy',5)
rdd=sc.parallelize([a,b,c])

现在我有兴趣在一个简单的类中捕获该RDD的不同属性,例如使用rdd.map(lambda s: getattr(s,'name'))从每个元素中提取name属性。

这个类的对象

class simple():
    def __init__(self,name):
        self.name=name
    def get_value(self):
        self.value = rdd.map(lambda s: getattr(s,self.name)).collect()

将设置其name并从RDD中获取相应的values

theAges = simple('age')
theAges.get_value()

然而,这遇到了一个错误,我认为该错误集中在self.name表达式中的lambda。这第二节工作正常

class simple2():
    def __init__(self,name):
        self.name=name
    def get_value(self):
        n=self.name
        self.value = rdd.map(lambda s: getattr(s,n)).collect() 

我添加的所有内容都是前一个电话n=self.name,并将n传递到lambda而不是self.name

问题是,我们无法在self.name内评估lambda?我在纯python中创建了一个类似的情况(在self.name中有lambda)并且没有错误,所以我认为这是Spark特有的。谢谢你的想法。

1 个答案:

答案 0 :(得分:1)

这是因为pyspark无法在类实例上创建闭包。在n范围内分配get_value允许Spark发送pickle函数,包括对象属性的别名。到目前为止,似乎解决方案是在函数范围内分配类属性(但不要指望它们发生变化!)