Scala 如何按计数排序并在值中保留唯一项
我有一个数据框,有两列,形式如下Scala 如何按计数排序并在值中保留唯一项,scala,apache-spark,spark-dataframe,Scala,Apache Spark,Spark Dataframe,我有一个数据框,有两列,形式如下 col1 col2 k1 'a' k2 'b' k1 'a' k1 'c' k2 'c' k1 'b' k1 'b' k2 'c' k1 'b' 我希望输出是 k1 ['b', 'a', 'c'] k2 ['c', 'b'] 因此,唯一的条目集,按每个条目出现的次数排序(降序排列)。在上面的示例中,“b”与k1关联三次,“a”关联两次,“c”关联一
col1 col2
k1 'a'
k2 'b'
k1 'a'
k1 'c'
k2 'c'
k1 'b'
k1 'b'
k2 'c'
k1 'b'
我希望输出是
k1 ['b', 'a', 'c']
k2 ['c', 'b']
因此,唯一的条目集,按每个条目出现的次数排序(降序排列)。在上面的示例中,“b”与k1关联三次,“a”关联两次,“c”关联一次
我该怎么做呢
groupBy($"col1").count()
只查看
col1
中的条目出现的次数,但这不是我要查找的 您可以执行以下操作:
df.groupBy($“col1”和$“col2”)
.agg(计数($“col2”).alias(“cnt”))
.groupBy($“col1”)
.agg(排序数组(收集列表(结构(-$“cnt”,“col2”))).as(“列表”))
.withColumn(“x”,“$”列表).getItem(“col2”))
.show(假)
因为排序\u数组
根据元素的自然顺序对元素进行升序排序-$“cnt”
有助于我们根据元素的计数按降序排序元素getItem
用于从结构中获取col2
的值
输出:
+----+------------------------+---------+
|col1 | list | x|
+----+------------------------+---------+
|k2[2,c],-1,b][c,b]|
|k1[3,b]、-2,a]、-1,c][b,a,c]|
+----+------------------------+---------+
import scala.collection.mutable
import org.apache.spark.sql.{Row}
val sort_by_count_udf = udf {
arr: mutable.WrappedArray[Row] =>
arr.map {
case Row(count: Long, col2: String) => (count, col2)
}.sortBy(-_._1).map { case (count, col2) => col2 }
}
val df = List(("k1", "a"),
("k1", "a"), ("k1", "c"), ("k1", "b"),
("k2", "b"), ("k2", "c"), ("k2", "c"),
("k1", "b"), ("k1", "b"))
.toDF("col1", "col2")
val grouped = df
.groupBy("col1", "col2")
.count()
.groupBy("col1")
.agg(collect_list(struct("count", "col2")).as("list"))
grouped.withColumn("list_ordered", sort_by_count_udf(col("list"))).show