我怎样才能使用'循环在Spark-Streaming&#D; DStream中进行转换和输出?

时间:2016-11-20 16:56:50

标签: python-2.7 apache-spark pyspark spark-streaming spark-dataframe

我是Spark的新手,我使用我定义的类生成了1000个不同的实例(这些实例中的函数相同,但详细的函数'参数不同)。sampler=generateClass()然后我需要映射那些实例'函数到我的Stream。(测试,只使用10和2个实例)

s=[]
for i in range(10):        
    s.append(mappedStream.map(lambda x: sampler[i].insert(x)).reduce(min))

uStream=ssc.union(s[0],s[1],s[2],s[3],s[4],s[5],s[6],s[7],s[8],s[9])
uStream.pprint()

但它的输出只是10个相同的键值对,似乎这些代码只是将我的数据映射到第一个实例,然后重复10次。

(85829323L, [2, 1])
(85829323L, [2, 1])
(85829323L, [2, 1])
(85829323L, [2, 1])
....

然后,我尝试

myStream1=mappedStream.map(lambda x: sampler[0].insert(x)).reduce(min)
myStream2=mappedStream.map(lambda x: sampler[1].insert(x)).reduce(min)
ssc.union(myStream1,myStream2).pprint()

输出正确:

(85829323L, [2, 1])
(99580454L, [4, 1])

为什么会这样?我该怎么处理呢?非常感谢你。

1 个答案:

答案 0 :(得分:0)

这是因为python lambda是惰性评估的,当你在s[0]上调用一个动作时,使用最后i参数计算(9在你的情况下,它是最后一个循环值)。

您可以使用函数生成器模式使用适当的i“强制”,例如:

def call_sampler(i):
    return lambda x: sampler[i].insert(x)

s=[]
for i in range(10):        
    s.append(mappedStream.map(call_sampler(i)).reduce(min))

uStream=ssc.union(s[0],s[1],s[2],s[3],s[4],s[5],s[6],s[7],s[8],s[9])
uStream.pprint()