Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/apache-spark/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 检索pyspark中每个数据帧组中的前n个_Python_Apache Spark_Dataframe_Pyspark_Apache Spark Sql - Fatal编程技术网

Python 检索pyspark中每个数据帧组中的前n个

Python 检索pyspark中每个数据帧组中的前n个,python,apache-spark,dataframe,pyspark,apache-spark-sql,Python,Apache Spark,Dataframe,Pyspark,Apache Spark Sql,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条具有相同用户id的记录,这些记录需要具有最高的分数。因此,结果应如下所示: user_id object_id score user_1 obj

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条具有相同用户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的新手,有谁能给我一个代码片段或这个问题的相关文档的入口吗?非常感谢

我认为您需要使用来获得基于
用户id
分数的每一行的排名,然后过滤您的结果以仅保留前两个值

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|
#+-------+---------+-----+----+

在获得秩相等时,如果使用
行数
而不是
,则Top-n更准确:

val n = 5
df.select(col('*'), row_number().over(window).alias('row_number')) \
  .where(col('row_number') <= n) \
  .limit(20) \
  .toPandas()
val n=5
df.select(col('*'),row_number().over(window.alias('row_number'))\

.where(col('row_number')我知道问题是针对
pyspark
提出的,我在
Scala
中寻找类似的答案,即

检索Scala中数据帧每组中的前n个值

这是@mtoto答案的
scala
版本

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
import org.apache.spark.sql.expressions.Window
导入org.apache.spark.sql.functions.rank
导入org.apache.spark.sql.functions.col
val window=window.partitionBy(“用户id”).orderBy(“分数描述”)
val rankByScore=rank().over(窗口)

df1.选择('*,rankByScore as'rank)。筛选(列(“rank”)以使用
ROW\u NUMBER()
函数在PYSPARK SQLquery中查找第n个最高值:

SELECT * FROM (
    SELECT e.*, 
    ROW_NUMBER() OVER (ORDER BY col_name DESC) rn 
    FROM Employee e
)
WHERE rn = N
N是该列所需的第N个最高值

输出:

[Stage 2:>               (0 + 1) / 1]++++++++++++++++
+-----------+
|col_name   |
+-----------+
|1183395    |
+-----------+

使用Python3和Spark 2.4查询将返回N个最高值

from pyspark.sql import Window
import pyspark.sql.functions as f

def get_topN(df, group_by_columns, order_by_column, n=1):
    window_group_by_columns = Window.partitionBy(group_by_columns)
    ordered_df = df.select(df.columns + [
        f.row_number().over(window_group_by_columns.orderBy(order_by_column.desc())).alias('row_rank')])
    topN_df = ordered_df.filter(f"row_rank <= {n}").drop("row_rank")
    return topN_df

top_n_df = get_topN(your_dataframe, [group_by_columns],[order_by_columns], 1) 
从pyspark.sql导入窗口
导入pyspark.sql.f函数
def get_topN(df,按列分组,按列排序,n=1):
window\u group\u by\u columns=window.partitionBy(group\u by\u columns)
有序_df=df.select(df.columns+[
f、 行号().over(窗口组按列排序。orderBy(order按列排序。desc()))。别名('row\u rank'))

topN_df=ordered_df.filter(f“row_rank这里是另一个没有窗口函数的解决方案,用于从pySpark数据帧获取前N条记录

# Import Libraries
from pyspark.sql.functions import col

# Sample Data
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"])

# Get top n records as Row Objects
row_list = df.orderBy(col("score").desc()).head(5)

# Convert row objects to DF
sorted_df = spark.createDataFrame(row_list)

# Display DataFrame
sorted_df.show()
输出

+-------+---------+-----+
|user_id|object_id|score|
+-------+---------+-----+
| user_1| object_2|    2|
| user_2| object_2|    2|
| user_1| object_1|    3|
| user_2| object_1|    5|
| user_2| object_2|    6|
+-------+---------+-----+

如果您对Spark中的更多窗口功能感兴趣,您可以参考我的一个博客:

我认为有一些地方需要调整。对象id对
groupby
top
过程都没有影响。我想要的是
groupby
用户id,并在每个组中检索具有最高sc的前两条记录另外,不仅仅是第一个记录。非常感谢!你可以在过滤器中使用窗口函数:
df.filter(rank().over(window))我大吃一惊……我确信我以前在过滤器中使用过窗口函数。但我确实无法复制它(无论是在2还是在1.6中)我用了一种异乎寻常的方式,但是我记不起来是什么时候或怎么做的。对不起,你可能想考虑使用<代码> RooSoxNo.<代码>而不是<代码> Reals<代码>,在获得相同的排名的情况下,你仍然想从PySpk.q.L.函数中导入NoCyto> <代码>。计算?我想也是这样。这是一种更有效的方法吗?我正在处理一个110 GB的数据集,有470万个类别(到groupBy),每个类别大约有4300行,它在一个大集群上永远占据一席之地。
+-------+---------+-----+
|user_id|object_id|score|
+-------+---------+-----+
| user_1| object_2|    2|
| user_2| object_2|    2|
| user_1| object_1|    3|
| user_2| object_1|    5|
| user_2| object_2|    6|
+-------+---------+-----+