Spark SQL Row_number()PartitionBy Sort Desc

时间:2016-02-06 22:17:26

标签: python apache-spark pyspark apache-spark-sql window-functions

我已经在Spark中使用Window成功创建了row_number() partitionBy,但是希望通过降序排序,而不是默认升序。这是我的工作代码:

from pyspark import HiveContext
from pyspark.sql.types import *
from pyspark.sql import Row, functions as F
from pyspark.sql.window import Window

data_cooccur.select("driver", "also_item", "unit_count", 
    F.rowNumber().over(Window.partitionBy("driver").orderBy("unit_count")).alias("rowNum")).show()

这给了我这个结果:

 +------+---------+----------+------+
 |driver|also_item|unit_count|rowNum|
 +------+---------+----------+------+
 |   s10|      s11|         1|     1|
 |   s10|      s13|         1|     2|
 |   s10|      s17|         1|     3|

在这里我添加desc()以降序:

data_cooccur.select("driver", "also_item", "unit_count", F.rowNumber().over(Window.partitionBy("driver").orderBy("unit_count").desc()).alias("rowNum")).show()

并收到此错误:

  

AttributeError:'WindowSpec'对象没有属性'desc'

我在这里做错了什么?

3 个答案:

答案 0 :(得分:33)

desc应该应用于列而不是窗口定义。您可以在列上使用任一方法:

from pyspark.sql.functions import col  

F.rowNumber().over(Window.partitionBy("driver").orderBy(col("unit_count").desc())

或独立功能:

from pyspark.sql.functions import desc

F.rowNumber().over(Window.partitionBy("driver").orderBy(desc("unit_count"))

答案 1 :(得分:0)

或者您可以在Spark-SQL中使用SQL代码:

from pyspark.sql import SparkSession

spark = SparkSession\
    .builder\
    .master('local[*]')\
    .appName('Test')\
    .getOrCreate()

spark.sql("""
    select driver
        ,also_item
        ,unit_count
        ,ROW_NUMBER() OVER (PARTITION BY driver ORDER BY unit_count DESC) AS rowNum
    from data_cooccur
""").show()

答案 2 :(得分:0)

更新实际上,我尝试对此进行更多研究,但似乎不起作用。 (实际上会引发错误)。之所以不起作用,是因为我在Databricks中对display()的调用下有这段代码(display()调用之后的代码永远不会运行)。似乎数据帧上的orderBy()orderBy()上的window实际上并不相同。我将仅保留此答案以作消极确认

从PySpark 2.4(可能更早)开始,只需将关键字ascending=False添加到orderBy调用中就可以了。

例如

personal_recos.withColumn("row_number", F.row_number().over(Window.partitionBy("COLLECTOR_NUMBER").orderBy("count", ascending=False)))

personal_recos.withColumn("row_number", F.row_number().over(Window.partitionBy("COLLECTOR_NUMBER").orderBy(F.col("count").desc())))

似乎给了我同样的行为。