我有一个Spark Dataframe,我想按键对元素进行分组,并将结果作为排序列表
目前我正在使用:
df.groupBy("columnA").agg(collect_list("columnB"))
如何使列表中的项目按升序排序?
答案 0 :(得分:20)
您可以尝试functions包中提供的功能sort_array
:
import org.apache.spark.sql.functions._
df.groupBy("columnA").agg(sort_array(collect_list("columnB")))
答案 1 :(得分:5)
只是想在Daniel de Paula的答案中添加关于sort_array
解决方案的另一个提示。
如果要根据不同的列对元素进行排序,则可以形成两个字段的结构:
由于结构是按字段进行排序的,因此您将获得所需的顺序,您所需要的就是摆脱结果列表每个元素中的排序依据列。
必要时,可以对多个 sort by 列应用相同的方法。
这是一个示例,可以在本地spark-shell
(使用:paste
模式下)中运行
import org.apache.spark.sql.Row
import spark.implicits._
case class Employee(name: String, department: String, salary: Double)
val employees = Seq(
Employee("JSMITH", "A", 20.0),
Employee("AJOHNSON", "A", 650.0),
Employee("CBAKER", "A", 650.2),
Employee("TGREEN", "A", 13.0),
Employee("CHORTON", "B", 111.0),
Employee("AIVANOV", "B", 233.0),
Employee("VSMIRNOV", "B", 11.0)
)
val employeesDF = spark.createDataFrame(employees)
val getNames = udf { salaryNames: Seq[Row] =>
salaryNames.map { case Row(_: Double, name: String) => name }
}
employeesDF
.groupBy($"department")
.agg(collect_list(struct($"salary", $"name")).as("salaryNames"))
.withColumn("namesSortedBySalary", getNames(sort_array($"salaryNames", asc = false)))
.show(truncate = false)
结果:
+----------+--------------------------------------------------------------------+----------------------------------+
|department|salaryNames |namesSortedBySalary |
+----------+--------------------------------------------------------------------+----------------------------------+
|B |[[111.0, CHORTON], [233.0, AIVANOV], [11.0, VSMIRNOV]] |[AIVANOV, CHORTON, VSMIRNOV] |
|A |[[20.0, JSMITH], [650.0, AJOHNSON], [650.2, CBAKER], [13.0, TGREEN]]|[CBAKER, AJOHNSON, JSMITH, TGREEN]|
+----------+--------------------------------------------------------------------+----------------------------------+