PySpark评估

时间:2016-06-28 18:46:24

标签: python apache-spark pyspark

我正在尝试以下代码,它为RDD中的每一行添加一个数字,并使用PySpark返回一个RDD列表。

from pyspark.context import SparkContext
file  = "file:///home/sree/code/scrap/sample.txt"
sc = SparkContext('local', 'TestApp')
data = sc.textFile(file) 
splits = [data.map(lambda p :  int(p) + i) for i in range(4)]
print splits[0].collect()
print splits[1].collect()
print splits[2].collect()

输入文件(sample.txt)中的内容为:

1
2
3

我期待这样的输出(在rdd中分别添加0,1,2的数字):

[1,2,3]
[2,3,4]
[3,4,5]

而实际输出是:

[4, 5, 6]
[4, 5, 6]
[4, 5, 6]

这意味着理解仅使用变量i的值3,而不考虑范围(4)

为什么会出现这种情况?

2 个答案:

答案 0 :(得分:4)

这是因为Python后期绑定而不是(Py)Spark特有的。使用i时将查找lambda p : int(p) + i,而不是在定义时查找def f(i): def _f(x): try: return int(x) + i except: pass return _f data = sc.parallelize(["1", "2", "3"]) splits = [data.map(f(i)) for i in range(4)] [rdd.collect() for rdd in splits] ## [[1, 2, 3], [2, 3, 4], [3, 4, 5], [4, 5, 6]] 。通常它意味着何时被调用,但在这个特定的上下文中,它被序列化以发送给工人。

你可以这样做:

(IsNUll((CAST(MHSE_ as varchar (20))),'')  + ' ' + isnull(MDIRCT,'') + ' ' +  IsNull(MSTRT,'') + ' ' + isnull(MSTTYP,'')) as FULLADDRESS

答案 1 :(得分:2)

这是因为lambdas引用了i via引用!它与火花无关。 See this

你可以试试这个:

a =[(lambda y: (lambda x: y + int(x)))(i) for i in range(4)]
splits = [data.map(a[x]) for x in range(4)]

或一行

splits = [
    data.map([(lambda y: (lambda x: y + int(x)))(i) for i in range(4)][x])
    for x in range(4)
]