火花中密集等级和行数的差异

时间:2017-07-07 10:48:22

标签: apache-spark

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

2 个答案:

答案 0 :(得分:34)

不同之处在于订购栏中存在“联系”。请查看以下示例:

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}在同一窗口(col2)内的col1 = "a"中存在两次。那是你看到三个功能之间的区别。

答案 1 :(得分:1)

我在 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|
+--------+---------+----+----------+----------+-----+

总而言之,如果您过滤 <= n 这些列,您将得到:

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