我有一个带有大量KeyVal条目的RDD。相同的密钥将出现多次,我有兴趣提取每个密钥的前N个条目。对Spark非常陌生,到目前为止,我一直无法弄清楚如何做到这一点,因此将不胜感激。
输入看起来像:
rdd = sc.parallelize([('a',1),('a',2),('b',3),('a',5),('b',4),('b',6)])
每个键的前2个条目所需的最终输出:
output = {'a':[1,2], 'b':[3,4]}
如果我通常只对前n个条目感兴趣,那么我当然可以将take(n)
应用于初始RDD。我正在寻找一种类似于take(n)
函数的方法,但是要遍历每个键。如果我可以创建一个仅包含原始RDD所需子集的RDD,那很好。之后再收集到字典中就没什么问题了。
因此,中间输出(RDD样式)将是:
[('a',1),('a',2),('b',3),('b',4)]
我如何在PySpark中实现这一目标?
编辑:建议的重复问题专门要求使用reduceByKey
的解决方案,在这种情况下不是必需的。
答案 0 :(得分:2)
在这里听孩子...
nLength = 2
rdd.groupByKey().map(lambda x: (x[0], list(x[1])[:nLength]))
说明:
rdd.groupByKey()
按键将RDD分组(在我们的示例中为“ a”或“ b”)。结果:
[('a',ResultIterable),('b',ResultIterable)]
.map(lambda x: (x[0], list(x[1])[:nLength]))
这部分创建一个元组:在左侧,键('a'或'b'),在右侧,我们从ResultIterable(x [1])创建一个列表,然后切割从0到nLength([:nLength])的列表。
享受!
答案 1 :(得分:0)
也许很简单,因为它可以完成这项工作:
rdd = sc.parallelize([('a',1),('a',2),('b',3),('a',5),('b',4),('b',6)])
n = 2
rdd.groupByKey().map(lambda x : (x[0], list(x[1])[:n])).collect()
输出:
[('b', [3, 4]), ('a', [1, 2])]
答案 2 :(得分:0)
尝试:
def slice_list(s,no_of_values):
return s[0:no_of_values]
rdd.groupByKey().map(lambda x: (x[0],slice_list( list(x[1]),2))).collect()