我有一个像这样的列表列表:
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'
我如何解决这个问题,使用内部地图或完成同样的事情?
答案 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。