Получить верхнюю часть n в каждой группе DataFrame в pyspark
Там находится DataFrame в pyspark с данными, как показано ниже:
user_id object_id score
user_1 object_1 3
user_1 object_1 1
user_1 object_2 2
user_2 object_1 5
user_2 object_2 2
user_2 object_2 6
Я ожидаю, что возвратит 2 записи в каждой группе с тем же user_id, который должен иметь самый высокий балл. Следовательно, результат должен выглядеть следующим образом:
user_id object_id score
user_1 object_1 3
user_1 object_2 2
user_2 object_2 6
user_2 object_1 5
Я действительно новичок в pyspark, может ли кто-нибудь дать мне фрагмент кода или портал для соответствующей документации по этой проблеме? Большое спасибо!
Ответы
Ответ 1
Я считаю, что вам нужно использовать функции окна для достижения ранга каждой строки на основе user_id
и score
, а затем фильтра ваши результаты сохраняют только первые два значения.
from pyspark.sql.window import Window
from pyspark.sql.functions import rank, col
window = Window.partitionBy(df['user_id']).orderBy(df['score'].desc())
df.select('*', rank().over(window).alias('rank'))
.filter(col('rank') <= 2)
.show()
#+-------+---------+-----+----+
#|user_id|object_id|score|rank|
#+-------+---------+-----+----+
#| user_1| object_1| 3| 1|
#| user_1| object_2| 2| 2|
#| user_2| object_2| 6| 1|
#| user_2| object_1| 5| 2|
#+-------+---------+-----+----+
В общем, официальное руководство по программированию является хорошим местом для начала изучения Искры.
Данные
rdd = sc.parallelize([("user_1", "object_1", 3),
("user_1", "object_2", 2),
("user_2", "object_1", 5),
("user_2", "object_2", 2),
("user_2", "object_2", 6)])
df = sqlContext.createDataFrame(rdd, ["user_id", "object_id", "score"])
Ответ 2
Top-n более точен, если вместо rank
использовать row_number
вместо равенства ранга:
val n = 5
df.select(col('*'), row_number().over(window).alias('row_number')) \
.where(col('row_number') <= n) \
.limit(20) \
.toPandas()
Примечание limit(20).toPandas()
трюк вместо show()
для ноутбуков Jupyter для лучшего форматирования.
Ответ 3
Я знаю, что вопрос задан для pyspark
, и я искал аналогичный ответ в Scala
, т.е.
Получить первые n значений в каждой группе DataFrame в Scala
Вот [@TG42] версия ответа @mtoto.
import org.apache.spark.sql.expressions.Window
import org.apache.spark.sql.functions.rank
import org.apache.spark.sql.functions.col
val window = Window.partitionBy("user_id").orderBy('score desc)
val rankByScore = rank().over(window)
df1.select('*, rankByScore as 'rank).filter(col("rank") <= 2).show()
# you can change the value 2 to any number you want. Here 2 represents the top 2 values
Больше примеров можно найти здесь here.
Ответ 4
Чтобы найти N-е наибольшее значение в SQL-запросе PYSPARK с помощью функции ROW_NUMBER()
:
SELECT * FROM (
SELECT e.*,
ROW_NUMBER() OVER (ORDER BY col_name DESC) rn
FROM Employee e
)
WHERE rn = N
N - это девятое наибольшее значение, требуемое из столбца
Выход:
[Stage 2:> (0 + 1) / 1]++++++++++++++++
+-----------+
|col_name |
+-----------+
|1183395 |
+-----------+
запрос вернет N наибольшее значение