【问题标题】:How to aggregate a data frame column into a new column of lists with count?如何将数据框列聚合到具有计数的新列表列中?
【发布时间】:2019-10-31 17:39:06
【问题描述】:

我在 scala 中有一个 spark 数据框,例如:

URL       Browser
A         Chrome
B         Chrome 
C         Firefox
A         Chrome
A         Firefox
A         Opera
A         Chrome
B         Chrome
B         Firefox
C         Tor

URL 列的数据范围很广,但 Browser 列的数据集有限。 我想在 URL 列上进行聚合,并按降序获取列表中每个浏览器的最高计数,例如:

URL      FrequentlyUsedBrowser 
A        [(Chrome,3),(Firefox,1),(Opera,1)]
B        [(Chrome,2),(Firefox,1)]
C        [(Chrome,1),(Tor,1)] 

我一直在为其编写 SQL 以使用窗口分区将计数作为每个浏览器的一个条目,但无法将其放入列表中。

这适用于运行 Spark 2.4 和 Scala 2.11 的 google 数据 proc 集群

【问题讨论】:

    标签: scala apache-spark apache-spark-sql


    【解决方案1】:

    您可以使用collect_list 并按sort_array 排序。

      df.withColumn("num", lit(1))
        .groupBy('url, 'browser)
        .agg(sum('num).as("num"))
        .select('url, format_string("(%s)",concat_ws(",", 'browser, 'num)).as("dst"))
        .groupBy('url)
        .agg(sort_array(collect_list('dst))).toDF("URL","FrequentlyUsedBrowser")
        .orderBy('url)
        .show(false)
    
    +---+-------+
    |url|browser|
    +---+-------+
    |  A| Chrome|
    |  B| Chrome|
    |  C|Firefox|
    |  A| Chrome|
    |  A|Firefox|
    |  A|  Opera|
    |  A| Chrome|
    |  B| Chrome|
    |  B|Firefox|
    |  C|    Tor|
    +---+-------+
    
    +---+------------------------------------+
    |URL|FrequentlyUsedBrowser               |
    +---+------------------------------------+
    |A  |[(Chrome,3), (Firefox,1), (Opera,1)]|
    |B  |[(Chrome,2), (Firefox,1)]           |
    |C  |[(Firefox,1), (Tor,1)]              |
    +---+------------------------------------+
    

    【讨论】:

    • 但这会按字母顺序排序...不是排序计数
    【解决方案2】:

    我对@chlebek 的答案进行了修改,添加了一个订单,因此它现在对我来说非常适合。该列表现在也已排序。谢谢!!

    df.withColumn("num", lit(1))
     .groupBy('url, 'browser)
     .agg(sum('num)
     .as("num"))
     .orderBy('num.desc)
     .select('url, format_string("(%s)",concat_ws(",", 'browser, 'num))
     .as("dst"))
     .groupBy('url)
     .agg(collect_list('dst))
     .toDF("URL","FrequentlyUsedBrowser")
     .orderBy('url).show(false)
    

    【讨论】:

      猜你喜欢
      • 2021-09-20
      • 1970-01-01
      • 2022-01-14
      • 2021-11-14
      • 2021-04-27
      • 1970-01-01
      • 1970-01-01
      • 2023-03-25
      • 1970-01-01
      相关资源
      最近更新 更多