如何在保留整行的同时获得具有最大值的单行?

lak*_*lak 0 scala apache-spark apache-spark-sql spark-dataframe

我想为每个 id 获取单行,其中仅存在 Charge 列的最大值。

示例输入数据:

id  name charge 
11  hg   10    
11  mm   20
22  aa   40
22  bb   40
Run Code Online (Sandbox Code Playgroud)

我试过的代码:

df.agg(max("charge"))
Run Code Online (Sandbox Code Playgroud)

我只得到最大值,如下所示:

charge
40   
Run Code Online (Sandbox Code Playgroud)

但是,我想保留整行:

id  name charge
11  mm   20
22  aa   40
22  bb   40
Run Code Online (Sandbox Code Playgroud)

如何保留前两列?name 列对于相同的 id 可以有不同的值,因此不可能groupBy在这两个列上使用并聚合结果。

如果两行具有相同的 id 并收费,则应保留两行。

Sha*_*ica 6

需要对列后的行进行分组id,然后charge在每组中找到该列的最大值。如您所见,如果groupBy用于实现此目的,该name列将消失。另一种方法是使用 awindow和 partition by id

为了确保当idcharge值相同但不同时保留两行name,最好的方法是添加一个新列maxCharge,然后添加filter数据框。

使用问题中的示例数据框:

val w = Window.partitionBy($"id")
val df2 = df.withColumn("maxCharge", max("charge").over(w))
  .filter($"maxCharge" === $"charge")
  .drop("charge")
  .withColumnRenamed("maxCharge", "charge")
Run Code Online (Sandbox Code Playgroud)

在这里,首先添加一个新列,其中每个id. 然后charge删除值小于此值的行。最后,新列被重命名charge以匹配所需的输出。

最后结果:

+---+----+------+
| id|name|charge|
+---+----+------+
| 22|  aa|    40|
| 22|  bb|    40|
| 11|  mm|    20|
+---+----+------+
Run Code Online (Sandbox Code Playgroud)

  • 太棒了。。非常感谢。 (2认同)