使用 sql 或 pandas 数据框获取前 5 行的 pyspark 数据框

Posted

技术标签:

【中文标题】使用 sql 或 pandas 数据框获取前 5 行的 pyspark 数据框【英文标题】:pyspark dataframe to get top 5 rows using sql or pandas dataframe 【发布时间】:2020-02-05 03:13:13 【问题描述】:

我正在尝试根据 rate_increase 获得每个地区的前 5 个项目。 我正在尝试使用 spark.sql 如下:

输入:

   district   item   rate_increase(%)
     Arba     coil    500
     Arba     pen    -85
     Arba     hat     50
     Cebu     oil    -40
     Cebu     pen     1100

Top5item = spark.sql('select district, item , rate_increase, ROW_NUMBER() OVER (PARTITION BY district ORDER BY rate_increase DESC) AS RowNum from rateTable where rate_increase > 0')

这很有效。 如何在同一个语句中过滤前 5 个产品。我尝试如下,是通过 spar.sql 更好的方法吗?

Top5item = spark.sql('select district, item from (select NCSA, Product, growthRate, ROW_NUMBER() OVER (PARTITION BY NCSA ORDER BY growthRate DESC) AS RowNum from rateTable where rate_increase > 0) where RowNum <= 5 order by NCSA')

输出:

   district   item   rate_increase(%)
     Arba     coil    500
     Arba     hat     50
     Cebu     pen     1100

谢谢。

【问题讨论】:

实际上由于某些原因,DESC 不起作用。什么是 groupby(district) 并获得前 5 项的嵌套方式?谢谢。 【参考方案1】:

莉莉, 您可以使用 pandas 从 csv 读取数据或创建如下所示的 pandas 数据帧,然后将其转换为 spark 数据帧

import pandas as pd

data_1 =  
    'district': ["Arba", "Arba", "Arba","Cebu", "Cebu"],
    'item': ['coil', 'pen', 'hat','oil','pen'],
    'rate_increase(%)': [500,-85,50,-40,1100]
    pandas_df = pd.DataFrame(data_1)
ddf_1 = spark.createDataFrame(pandas_df)
ddf_1.createOrReplaceTempView("ddf_1")

output = spark.sql("""

select district, item , `rate_increase(%)` from (
  select row_number() over (partition by district order by `rate_increase(%)` desc) as RowNum, district,item, `rate_increase(%)`  from ddf_1  where  `rate_increase(%)` > 0 )
where RowNum <= 5 order by district, RowNum

""")

output.show()

+--------+----+----------------+
|district|item|rate_increase(%)|
+--------+----+----------------+
|    Arba|coil|             500|
|    Arba| hat|              50|
|    Cebu| pen|            1100|
+--------+----+----------------+

【讨论】:

【参考方案2】:

记住查询的执行顺序:

From/Joins -> Where -> Group by -> Have -> Select

where 子句where RowNum &lt;= 5 不起作用,因为它不知道RowNum 是什么。

尝试使用子查询块:

spark.sql("""

select district, item , `rate_increase(%)` from (
  select row_number() over (partition by district order by `rate_increase(%)` desc) as RowNum, district,item, `rate_increase(%)`  from ddf_1  where  `rate_increase(%)` > 0 )
where RowNum <= 5 order by district, RowNum

""").show()

输出:

+--------+----+----------------+
|district|item|rate_increase(%)|
+--------+----+----------------+
|    Arba|coil|             500|
|    Arba| hat|              50|
|    Cebu| pen|            1100|
+--------+----+----------------+

【讨论】:

谢谢。 order by `rate_increase(%)` desc 不工作。它不是按降序选择值。 pyspark数据框df = spark.sql('select district, item, `rate_increase(%)` from ddf_1 where v &gt; 0')有没有简单的解决方案谢谢 我得到了正确的答案。检查您的 rate_increase(%) 是否具有正确的数据类型 数据类型是对象类型,因此必须将其转换为浮点类型并使用熊猫完成任务,如下所示。如果我必须使用您的解决方案,我该怎么做。我的数据实际上是从 csv 读取的。谢谢【参考方案3】:

我尝试使用 pandas 作为一个简单的解决方案。

Top5item = df.sort_values('rate_increase(%)', ascending = True).groupby(['district']).head(5)

按区分组后升序(rate_increase(%))还是不行。谢谢

【讨论】:

我设法使用 pandas 如下:df.groupby('district').apply(lambda grp: grp.nlargest(5, 'rate_increase(%)')) 棘手的部分是我必须将 rate_increase(%) 更改为 int 类型才能使其工作。有任何可用的 pyspark 解决方案吗?谢谢

以上是关于使用 sql 或 pandas 数据框获取前 5 行的 pyspark 数据框的主要内容,如果未能解决你的问题,请参考以下文章

如何将 sql 表保存为 pandas 数据框?

使用 PYODBC 从 pandas 获取数据到 SQL 服务器

动态构建大型数据框(spark 或 pandas)以导出到 csv 的方法

将外部 SQL 文件读入 Pandas 数据框

在 pandas 数据框中使用多个行或列值进行计算

如何获取多索引数据帧的前两个索引的字典