Python 根据分数Pypspark为另一列中的每个值筛选列中前N个值
因此,我在Spark中有一个数据框,包含以下数据: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
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|
+-------+------+---------+-----+