Python 根据分数Pypspark为另一列中的每个值筛选列中前N个值

Python 根据分数Pypspark为另一列中的每个值筛选列中前N个值,python,dataframe,apache-spark,pyspark,apache-spark-sql,Python,Dataframe,Apache Spark,Pyspark,Apache Spark Sql,因此,我在Spark中有一个数据框,包含以下数据: user_id item category score ------------------------------- user_1 item1 categoryA 8 user_1 item2 categoryA 7 user_1 item3 categoryA 6 user_1 item4 categoryD 5 user_1 item5 categoryD 4 user_2 item6 categor

因此,我在Spark中有一个数据框,包含以下数据:

user_id item   category score
-------------------------------
user_1  item1  categoryA  8
user_1  item2  categoryA  7
user_1  item3  categoryA  6
user_1  item4  categoryD  5
user_1  item5  categoryD  4
user_2  item6  categoryB  7
user_2  item7  categoryB  7
user_2  item8  categoryB  7
user_2  item9  categoryA  4
user_2  item10 categoryE  2
user_2  item11 categoryE  1
我想对其进行过滤,以便根据分数为每个用户只保留相同类别的2个项目,因此它应该如下所示:

user_id item   category score
-------------------------------
user_1  item1  categoryA  8
user_1  item2  categoryA  7
user_1  item4  categoryD  5
user_1  item5  categoryD  4
user_2  item7  categoryB  7
user_2  item8  categoryB  7
user_2  item9  categoryA  4
user_2  item10 categoryE  2
user_2  item11 categoryE  1
其中第3项和第6项由于是用户同一类别的第三项而被删除,并且得分较低(或者如果得分相等,则随机删除,直到该类别只有两项)

我试着在窗口上设置一个分区,如下所示:

df2 = test.withColumn(
    'rank', 
    F.rank().over(Window.partitionBy('user_id','category').orderBy(F.desc('score')))
).filter('rank <= 2')
这适用于用户1,但不适用于用户2,因为它具有相同类别的项目,分数相等,因此对于属于categoryB且分数为7的项目6、7、8,不会过滤掉任何项目。在这个边缘的情况下,我想过滤一个随机只有2


您知道如何进行这种过滤吗?

您可以在按用户id和类别划分的窗口上使用
行号

df2 = df.withColumn(
    'rank',
    F.row_number().over(Window.partitionBy('user_id', 'category').orderBy(F.desc('score')))
).filter('rank <= 2').drop('rank').orderBy('user_id', 'item', 'category', F.desc('score'))

df2.show()
+-------+------+---------+-----+
|user_id|  item| category|score|
+-------+------+---------+-----+
| user_1| item1|categoryA|    8|
| user_1| item2|categoryA|    7|
| user_1| item4|categoryD|    5|
| user_1| item5|categoryD|    4|
| user_2|item10|categoryE|    2|
| user_2|item11|categoryE|    1|
| user_2| item7|categoryB|    7|
| user_2| item8|categoryB|    5|
| user_2| item9|categoryA|    4|
+-------+------+---------+-----+
df2=df.withColumn(
"排名",,
F.行号().over(Window.partitionBy('user\u id','category')。orderBy(F.desc('score'))

).过滤器('rank Hi!我也试过了,但它对相同分数的同一类别的项目不起作用,我也想将它们归档。我将用示例编辑主要帖子。谢谢answer@JaimeFerrandoHuertas您可以改用
行号
。编辑我的答案。这就是我要找的!谢谢您的答案,很抱歉没有包括第一次的边缘案例。
df2 = df.withColumn(
    'rank',
    F.row_number().over(Window.partitionBy('user_id', 'category').orderBy(F.desc('score')))
).filter('rank <= 2').drop('rank').orderBy('user_id', 'item', 'category', F.desc('score'))

df2.show()
+-------+------+---------+-----+
|user_id|  item| category|score|
+-------+------+---------+-----+
| user_1| item1|categoryA|    8|
| user_1| item2|categoryA|    7|
| user_1| item4|categoryD|    5|
| user_1| item5|categoryD|    4|
| user_2|item10|categoryE|    2|
| user_2|item11|categoryE|    1|
| user_2| item7|categoryB|    7|
| user_2| item8|categoryB|    5|
| user_2| item9|categoryA|    4|
+-------+------+---------+-----+