如何在pyspark中使用map / lambda中的map / lambda?

时间:2015-12-12 03:05:40

标签: python lambda apache-spark pyspark

我有一个像这样的列表列表:

b = [['r','w'],['n','finished']]

我希望能够对每个列表中的每个元素进行操作。

我可以在python中本地执行此操作:

result = b.map(lambda aList: \
           map(lambda aString: \
                              '' if aString.strip().lower() in [' finish', 'finished', 'terminate', 'done'] else aString,\
                              aList))

但是,Spark无法序列化内部map

 File "/<path>/python/pyspark/worker.py", line 88, in main
12/11/2015 18:24:49 [launcher]      command = pickleSer._read_with_length(infile)
12/11/2015 18:24:49 [launcher]    File "//<path>/spark/python/pyspark/serializers.py", line 156, in _read_with_length
12/11/2015 18:24:49 [launcher]      return self.loads(obj)
12/11/2015 18:24:49 [launcher]    File "//<path>//python/pyspark/serializers.py", line 405, in loads
12/11/2015 18:24:49 [launcher]      return cPickle.loads(obj)
12/11/2015 18:24:49 [launcher]  AttributeError: 'module' object has no attribute 'map'

我如何解决这个问题,使用内部地图或完成同样的事情?

2 个答案:

答案 0 :(得分:4)

处理此问题的一种方法:

to_replace = ['finish', 'finished', 'terminate', 'done'] 

rdd = sc.parallelize([['r','w'],['n','finished']])
rdd.map(lambda xs: ['' if  x.strip().lower() in to_replace else x for x in xs])

一般来说,如果你发现自己在考虑嵌套函数,那么你应该使用普通函数而不是lambda表达式是一个好兆头。

答案 1 :(得分:2)

或者使用@ zero323的模板,如果您使用的是Python 2.x,则可以使用map代替for,但这是python问题,而不是pyspark 1}}一个,效果是一样的。

to_replace = ['finish', 'finished', 'terminate', 'done'] 

rdd = sc.parallelize([['r','w'],['n','finished']])
rdd.map(
    lambda xs: map(lambda x: "" if x.strip().lower() in to_replace else x, xs)
)

但是,如果to_replace列表非常大,则应使用broadcast variable