我要使用以下rdd
rdd = sc.parallelize([("K1", "e", 9), ("K1", "aaa", 9), ("K1", "ccc", 3), ("K1", "ddd", 9),
("B1", "qwe", 4), ("B1", "rty", 7), ("B1", "iop", 8), ("B1", "zxc", 1)])
获取输出
[('K1', 'aaa', 9),
('K1', 'ddd', 9),
('K1', 'e', 9),
('B1', 'iop', 8),
('B1', 'rty', 7),
('B1', 'qwe', 4)]
我提到了Get Top 3 values for every key in a RDD in Spark,并使用了以下代码
from heapq import nlargest
rdd.groupBy(
lambda x: x[0]
).flatMap(
lambda g: nlargest(3, g[1], key=lambda x: (x[2],x[1]))
).collect()
但是,我只能得出
[('K1', 'e', 9),
('K1', 'ddd', 9),
('K1', 'aaa', 9),
('B1', 'iop', 8),
('B1', 'qwe', 7),
('B1', 'rty', 4)]
我该怎么办?
答案 0 :(得分:1)
实际上这是一个排序问题,但是由于sorting
,shuffling
是一个计算上非常昂贵的过程。但是您可以尝试:
rdd2 = rdd.groupBy(
lambda x: x[0]
).flatMap(
lambda g: nlargest(3, g[1], key=lambda x: (x[2],x[1]))
)
rdd2.sortBy(lambda x: x[1], x[2]).collect()
# [('K1', 'aaa', 9), ('K1', 'ddd', 9), ('K1', 'e', 9), ('B1', 'iop', 8), ('B1', 'qwe', 4), ('B1', 'rty', 7)]
我已经使用元组的第一个和第二个值对它进行了排序。
还请注意,q
按字母顺序排在r
之前。因此,您提到的预期输出不正确且具有误导性。
答案 1 :(得分:0)
如果您对数据框开放,则可以将windows
函数与rank
一起使用
灵感来自here
import pyspark.sql.functions as f
from pyspark.sql import functions as F
from pyspark.sql import SparkSession
from pyspark.sql import Window
spark = SparkSession.builder.appName('test').master("local[*]").getOrCreate()
df = spark.createDataFrame([
("K1", "e", 9),
("K1", "aaa", 9),
("K1", "ccc", 3),
("K1", "ddd", 9),
("B1", "qwe", 4),
("B1", "rty", 7),
("B1", "iop", 8),
("B1", "zxc", 1)], ['A', 'B', 'C']
)
w = Window.partitionBy('A').orderBy(df.C.desc())
df.select('*', F.rank().over(w).alias('rank')).filter("rank<4").drop('rank').show()
+---+---+---+
| A | B | C|
+---+---+---+
| B1 | iop | 8|
| B1 | rty | 7|
| B1 | qwe | 4|
| K1 | e | 9|
| K1 | aaa | 9|
| K1 | ddd | 9|
+---+---+---+