注意到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特有的。谢谢你的想法。
答案 0 :(得分:1)
这是因为pyspark无法在类实例上创建闭包。在n
范围内分配get_value
允许Spark发送pickle函数,包括对象属性的别名。到目前为止,似乎解决方案是在函数范围内分配类属性(但不要指望它们发生变化!)