我有一个Spark RDD,如下所示:
[(1, ...),
(1, ...),
(2, ...),
(3, ...)]
我正在尝试删除具有重复键的记录,在这种情况下,我想要排除所有具有键'1'的记录。我想要的最终输出应该看起来像
[(2, ...),
(3, ...)]
到目前为止我尝试过的,它有效,但我的直觉说应该有更好的解决方案:
>> a = sc.parallelize([(1,[1,1]), (1,[1,1]), (2,[1,1]), (3,[1,1])])
>> print a.groupByKey() \
.filter(lambda x: len(x[1])==1 ) \
.map(lambda x: (x[0], list(x[1])[0] )).collect()
[(2, [1, 1]), (3, [1, 1])]
任何人都可以帮我这个吗?
答案 0 :(得分:1)
另外两个选择:
subtractByKey
- 这需要改组,因此总费用可能与groupByKey
相似。您可以选择将输入RDD
和preservesPartitioning
分区设置为True
:
from operator import add
counts = (a.keys()
.map(lambda x: (x, 1))
.reduceByKey(add))
duplicates = (counts
.filter(lambda x: x[1] > 1)
.map(lambda x: (x[0], None)))
a.subtractByKey(duplicates)
广播变量:
正过滤器 - 如果您预计会有大量重复
non_duplicated = sc.broadcast(set(
counts.filter(lambda x: x[1] == 1).keys().collect()
))
a.filter(lambda x: x[0] in non_duplicated.value)
负面过滤器 - 如果预期重复数量较少
duplicated = sc.broadcast(set(
counts.filter(lambda x: x[1] > 1).keys().collect()
))
a.filter(lambda x: x[0] not in duplicated.value)