【问题标题】:Spark RDD remove records with multiple keysSpark RDD 删除具有多个键的记录
【发布时间】:2015-10-16 11:16:07
【问题描述】:

我有一个如下所示的 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])]

谁能帮我解决这个问题?

【问题讨论】:

  • 您能否接受答案或解释为什么它不起作用以便改进?在此先感谢:)
  • 另外,如果你可以看看这个stackoverflow.com/q/33157978/1560062 如果你没有找到有用的答案,我会删除。

标签: python apache-spark pyspark


【解决方案1】:

另外两个选项:

  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)
    
  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)
      

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-06-23
    • 2019-10-13
    相关资源
    最近更新 更多