【问题标题】:How to get a single row with the maximum value while keeping the whole row? [duplicate]如何在保持整行的同时获得具有最大值的单行? [复制]
【发布时间】:2018-07-10 01:24:45
【问题描述】:
我想为每个 id 获取单行,其中仅存在 charge 列的最大值。
输入数据示例:
id name charge
11 hg 10
11 mm 20
22 aa 40
22 bb 40
我尝试过的代码:
df.agg(max("charge"))
我只得到最大值,像这样:
charge
40
但是,我想保留整行:
id name charge
11 mm 20
22 aa 40
22 bb 40
如何同时保留前两列? name 列对于同一个 id 可以有不同的值,因此不能在这两个列上使用 groupBy 并聚合结果。
如果两行具有相同的 id 和费用,则应保留两行。
【问题讨论】:
标签:
scala
apache-spark
apache-spark-sql
spark-dataframe
【解决方案1】:
需要将id列之后的行分组,然后在每组中找到charge列的最大值。如果使用groupBy 来实现此目的,则name 列将消失,正如您所注意到的。另一种方法是使用window 并按id 进行分区。
为了确保在id 和charge 的值相同但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")
在这里,首先添加一个新列,其中包含每个id 的最大值。然后删除charge 值小于此值的行。最后,将新列重命名为 charge 以匹配所需的输出。
最终结果:
+---+----+------+
| id|name|charge|
+---+----+------+
| 22| aa| 40|
| 22| bb| 40|
| 11| mm| 20|
+---+----+------+
【解决方案2】:
第一步应该是按 id 分组并获取 max(charge) 作为新列。
第二步应该是加入input.id=grouped_data.id和input.charge=grouped_data.charge上的输入和分组数据集。
input:
id name charge
11 hg 10
11 mm 20
22 aa 40
22 bb 40
grouped_data_on_id:
id max(charge)
11 20
22 40
joined_data_on_id_and_charge:
id name charge
11 hg 10
22 aa 40
22 bb 40