我有一个表格
的数组val array: Array[(Int, (String, Int))] = Array(
(idx1,(word1,count1)),
(idx2,(word2,count2)),
(idx1,(word1,count1)),
(idx3,(word3,count1)),
(idx4,(word4,count4)))
我想从每个索引(idx1,idx2,....)获取此数组的前10个和后10个元素。基本上我想要每个索引值的前10个最常见和最低10个最少出现的元素。
请建议如何以最有效的方式实现火花。 我已经尝试过为每个索引使用for循环,但这会使程序太慢而且顺序运行。
一个例子是:
(0,("apple",1))
(0,("peas",2))
(0,("banana",4))
(1,("peas",2))
(1,("banana",1))
(1,("apple",3))
(2,("NY",3))
(2,("London",5))
(2,("Zurich",6))
(3,("45",1))
(3,("34",4))
(3,("45",6))
Suppose I do top 2 on this set output would be
(0,("banana",4))
(0,("peas",2))
(1,("apple",3))
(1,("peas",2))
(2,("Zurich",6))
(2,("London",5))
(3,("45",6))
(3,("34",4))
我也需要同样的底部2
答案 0 :(得分:0)
不确定火花,但我认为你可以使用类似的东西:
def f(array: Array[(Int, (String, Int))], n:Int) =
array.groupBy(_._1)
.map(pair => (
pair._1,
pair._2.sortBy(_._2).toList
)
)
.map(pair => (
pair._1,
(
pair._2.take(Math.min(n, pair._2.size)),
pair._2.drop(Math.max(0, pair._2.size - n))
)
)
)
groupBy通过频率将索引映射返回到条目的排序列表中。在此之后,将这些条目映射到一对列表,一个列表包含前n个元素,另一个包含底部n个元素。请注意,您可以用_替换所有命名参数,为清楚起见,我这样做了。
此版本假设您始终对计算top和bot n元素感兴趣,因此只需一次通过。如果你通常只需要两个中的一个,那么在toList之后立即添加.take或.drop会更有效。
答案 1 :(得分:0)
我理解这相当于通过在(K,V)对上使用groupByKey生成整个列列表,然后对其进行排序操作。尽管操作是正确的,但在典型的spark环境中,groupByKey操作将涉及大量的shuffle输出,这可能导致操作效率低下。