如何将数据框列聚合到带有count的新列表列中?

时间:2019-10-30 10:05:52

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

我在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”列中的数据范围很广,但是“浏览器”列中的数据集有限。 我想汇总在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数据处理集群

2 个答案:

答案 0 :(得分: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)]              |
+---+------------------------------------+

答案 1 :(得分:0)

我对@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)