【问题标题】:Difference in dense rank and row number in sparkspark中密集等级和行数的差异
【发布时间】:2017-07-07 10:48:21
【问题描述】:

我试图了解密集等级和行号之间的区别。每个新窗口分区都从 1 开始。行的等级不总是从 1 开始吗?任何帮助将不胜感激

【问题讨论】:

    标签: apache-spark


    【解决方案1】:

    不同之处在于排序列中有“关系”。检查以下示例:

    import org.apache.spark.sql.expressions.Window
    import org.apache.spark.sql.functions._
    
    val df = Seq(("a", 10), ("a", 10), ("a", 20)).toDF("col1", "col2")
    
    val windowSpec = Window.partitionBy("col1").orderBy("col2")
    
    df
      .withColumn("rank", rank().over(windowSpec))
      .withColumn("dense_rank", dense_rank().over(windowSpec))
      .withColumn("row_number", row_number().over(windowSpec)).show
    
    +----+----+----+----------+----------+
    |col1|col2|rank|dense_rank|row_number|
    +----+----+----+----------+----------+
    |   a|  10|   1|         1|         1|
    |   a|  10|   1|         1|         2|
    |   a|  20|   3|         2|         3|
    +----+----+----+----------+----------+
    

    请注意,值“10”在同一窗口 (col1 = "a") 内的 col2 中存在两次。这就是您看到这三个功能之间的区别的时候。

    【讨论】:

    • @daniel 这是一个出色的答案,具有出色的视觉元素,可以将要点带回家。
    • @JasonWolosonovich 感谢您的反馈。
    • 很好的视觉解释
    • 另外,使用它可以获得唯一的行号,而无需按任何特定列进行分区: df.withColumn('row_num' , row_number().over(Window.partitionBy().orderBy( col('some_df_col')))
    【解决方案2】:

    我正在用 Python 显示 @Daniel 的答案,并且我正在添加与 count('*') 的比较,如果您希望每组最多获得前 n 行,可以使用该比较。

    from pyspark.sql.session import SparkSession
    from pyspark.sql import Window
    from pyspark.sql import functions as F
    
    spark = SparkSession.builder.getOrCreate()
    
    df = spark.createDataFrame([
        ['a', 10], ['a', 20], ['a', 30],
        ['a', 40], ['a', 40], ['a', 40], ['a', 40],
        ['a', 50], ['a', 50], ['a', 60]], ['part_col', 'order_col'])
    
    window = Window.partitionBy("part_col").orderBy("order_col")
    
    df = (df
      .withColumn("rank", F.rank().over(window))
      .withColumn("dense_rank", F.dense_rank().over(window))
      .withColumn("row_number", F.row_number().over(window))
      .withColumn("count", F.count('*').over(window))
    )
    
    df.show()
    
    +--------+---------+----+----------+----------+-----+
    |part_col|order_col|rank|dense_rank|row_number|count|
    +--------+---------+----+----------+----------+-----+
    |       a|       10|   1|         1|         1|    1|
    |       a|       20|   2|         2|         2|    2|
    |       a|       30|   3|         3|         3|    3|
    |       a|       40|   4|         4|         4|    7|
    |       a|       40|   4|         4|         5|    7|
    |       a|       40|   4|         4|         6|    7|
    |       a|       40|   4|         4|         7|    7|
    |       a|       50|   8|         5|         8|    9|
    |       a|       50|   8|         5|         9|    9|
    |       a|       60|  10|         6|        10|   10|
    +--------+---------+----+----------+----------+-----+
    

    例如,如果您想最多取 4 个而不随机选择排序列的 4 个“40”之一:

    df.where("count <= 4").show()
    
    +--------+---------+----+----------+----------+-----+
    |part_col|order_col|rank|dense_rank|row_number|count|
    +--------+---------+----+----------+----------+-----+
    |       a|       10|   1|         1|         1|    1|
    |       a|       20|   2|         2|         2|    2|
    |       a|       30|   3|         3|         3|    3|
    +--------+---------+----+----------+----------+-----+
    

    总而言之,如果您过滤&lt;= n 这些列,您将获得:

    • rank 至少 n 行
    • dense_rank 至少 n 个不同的 order_col 值
    • row_number 正好 n 行
    • count最多n行

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-07-04
      • 2017-02-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-03-27
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多