Spark RDD删除具有多个键的记录

时间:2015-10-16 02:17:12

标签: python apache-spark pyspark

我有一个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])]

任何人都可以帮我这个吗?

1 个答案:

答案 0 :(得分:1)

另外两个选择:

  1. subtractByKey - 这需要改组,因此总费用可能与groupByKey相似。您可以选择将输入RDDpreservesPartitioning分区设置为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)
    
  2. 广播变量:

    • 正过滤器 - 如果您预计会有大量重复

      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)