使用PySpark编程并行化

时间:2018-01-20 09:07:58

标签: python apache-spark parallel-processing pyspark

我对PySpark有点新意,我正在研究如何使用PySpark并行化一个简单的程序。我没有找到可以正确进行这种处理的Spark转换。

我想要做的处理在某种程度上过滤了一个非常大的有序向量/列表的一些数值。在得到的矢量中,所有2个连续值之间的差值应该是> = X(给出X)。也应该保留初始向量的第一个值。

EG。 v =(1,3,4,7,8,11),X = 3,结果是v'=(1,4,7,11)。

该程序在“经典”Python中实现非常简单,但需要使用Spark并行化非常快速地获得结果。

##### myDF = data from database
last_retained_value = 0 ### all values in myDF are positive
for value in myDF.collect():
    current_value = value
    if (current_value - last_retained_value >= X): ### X is fixed
        last_retained_value = current_value
        result.append(str(current_value)) ### result is a list which contains final result**

非常感谢你。

1 个答案:

答案 0 :(得分:0)

您拥有的顺序解决方案看起来并不可行,因为每个元素的命运取决于完整的历史记录(删除单个项目可能会影响位于其后面的所有项目)。

通过首先修剪分区很容易获得近似的顺序代码:

d = 3

rdd = sc.parallelize([1, 3, 4, 7, 8, 11], 4)

def prune(xs, d=3):
    prev = None
    for x in xs: 
        if prev is None or abs(x - prev) >= d:
            prev = x
            yield x

pruned = rdd.mapPartitions(prune)

然后再次扫描

borders = pruned.mapPartitions(lambda xs: [max(xs)]).collect()

pruned.filter(lambda x: any(b < x < b + 3 for b in borders)).collect()
# [3, 8]

但正如您所看到的,这种方法不那么保守,并且不会返回与顺序解决方案相同的结果。

对于较大的分区,以及max(p)和min(p + 1)之间的随机分布差异,其中p是分区,这应该平均收敛到类似的输出,但没有任何保证。

如果您想按组应用它,您只需repartitionAndSortWithinPartitions并为每个分区应用本地逻辑。