我对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**
非常感谢你。
答案 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
并为每个分区应用本地逻辑。