如何为spark中另一列中的每个唯一值找到一列的最大值?

xv8emn3q  于 2021-05-19  发布在  Spark
关注(0)|答案(2)|浏览(496)

假设我有一个类似的数据集:

我的最终产品需要为一周中的每一天与当天活动最多的地方排成一行。i、 我试过使用window函数,使用max和groupie,但是我把自己弄糊涂了。

jtoj6r0c

jtoj6r0c1#

为了你的目的你需要写 window function :

val df = Seq(
  ("Mon", "Place A", 10),
  ("Mon", "Place B", 42),
  ("Wed", "Place C", 41),
  ("Thurs", "Place D", 45),
  ("Fri", "Place E", 64),
  ("Fri", "Place A", 12),
  ("Wed", "Place F", 54),
  ("Wed", "Place A", 1)
).toDF("day", "place", "number")
df.show()
df.withColumn("orderedNumberForDay",
  row_number()
    .over(
      Window.orderBy(col("number").desc)
        .partitionBy("day")
    )
).filter(col("orderedNumberForDay") === lit(1))
 .select("day", "place", "number")
 .show()
/*                            
+-----+-------+------+        +-----+-------+------+
|  day|  place|number|        |  day|  place|number|
+-----+-------+------+        +-----+-------+------+
|  Mon|Place A|    10|        |  Mon|Place B|    42|
|  Mon|Place B|    42|  ===>> |  Wed|Place F|    54|
|  Wed|Place C|    41|        |  Fri|Place E|    64|
|Thurs|Place D|    45|        |Thurs|Place D|    45|
|  Fri|Place E|    64|        +-----+-------+------+
|  Fri|Place A|    12|   
|  Wed|Place F|    54|   
|  Wed|Place A|     1|   
+-----+-------+------+

* /

只是解释一下它是怎么工作的
首先,您需要添加列 window function 结果如下:

df.withColumn("orderedNumberForDay",
  row_number()
    .over(
      Window.orderBy(col("number").desc)
      .partitionBy("day")
    )
)
``` `row_number()` -是你房间里的排数 `partition` .  `Partition` 就像一个团队 `group by` .  `partitionBy("day")` 只是用相同的 `day` 列值。最后我们要点这个 `window` 由 `number` 在 `desc` 有秩序,就有秩序 `orderBy(col("number").desc` 在我们的 `window function` .  `over` 就像一座桥 `windows` 里面有一些有用的计算 `windows` 它只是绑定 `row_number` 以及 `window function` .
执行此阶段后,我们将获得以下数据:

+-----+-------+------+-------------------+
| day| place|number|orderedNumberForDay|
+-----+-------+------+-------------------+
| Mon|Place B| 42| 1|
| Mon|Place A| 10| 2|
| Wed|Place F| 54| 1|
| Wed|Place C| 41| 2|
| Wed|Place A| 1| 3|
| Fri|Place E| 64| 1|
| Fri|Place A| 12| 2|
|Thurs|Place D| 45| 1|
+-----+-------+------+-------------------+

所以,我们只需要 `filter` 带的行 `orderedNumberForDay` 等于 `1` -它将与
max `number` 并选择开始列: `day, place, number` . 最终结果将是:

+-----+-------+------+
| day| place|number|
+-----+-------+------+
| Mon|Place B| 42|
| Wed|Place F| 54|
| Fri|Place E| 64|
|Thurs|Place D| 45|
+-----+-------+------+

ttcibm8c

ttcibm8c2#

spark 3.0引入了聚合函数max\u,它正好满足您的需求:

df.groupBy("day")
   .agg(expr("max_by(place, number)"), max('number))
   .show()

结果:

+-----+---------------------+-----------+
|  day|max_by(place, number)|max(number)|
+-----+---------------------+-----------+
|  Mon|              Place B|         42|
|  Wed|              Place F|         54|
|  Fri|              Place E|         64|
|Thurs|              Place D|         45|
+-----+---------------------+-----------+

相关问题