Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/apache-spark/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Scala 如何按计数排序并在值中保留唯一项_Scala_Apache Spark_Spark Dataframe - Fatal编程技术网

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
中的条目出现的次数,但这不是我要查找的

您可以执行以下操作:

  • 对于每个键和列值,计算计数
  • 对于每个键,计算一个包含所有相关列值及其计数的列表
  • 使用udf对列表进行排序并删除计数
  • 这样(在Scala中):

    这里有一个(不是很漂亮的解决方案)只使用内置函数:

    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