【问题标题】:Spark DataFrame aggregate multiple column into one column as a stringSpark DataFrame 将多列聚合为一列作为字符串
【发布时间】:2018-10-27 10:27:07
【问题描述】:

我想将一个 Spark DataFrame 转换为另一个 DataFrame,具体方式如下:

我有 Spark DataFrame:

+---------+------------+
|protocol |   count    |
+---------+------------+
|      TCP|    8231    |
|     ICMP|    7314    |
|      UDP|    5523    |
|     IGMP|    4423    |
|      EGP|    2331    |
+---------+------------+

我想把它变成:

+----------------------------------------------------------+
|Aggregated                                                |
+----------------------------------------------------------+
|{tcp: 8231, icmp: 7314, udp: 5523, igmp: 4423, egp: 2331} |
+----------------------------------------------------------+

聚合列可以是列表或地图,也可以是字符串。这可以通过 DataFrame 函数实现,还是我需要创建自己的 udf 来聚合它?

【问题讨论】:

  • 执行此操作时是否要使用数据框中的所有行?由于数量不多,因此收集数据并使用纯 Scala 进行转换可能会更容易。
  • @Shaido 是的,所有行,但给出的示例并不是唯一存在的行。随着时间的推移,行数会不断增加

标签: scala apache-spark dataframe dataset


【解决方案1】:

连接数据框中的列并创建一个新列:

var new_df = df.withColumn("concat", concat($"protocol", lit(" : "), $"count"))

要将其作为列表聚合到单行中,您可以这样做。

var new_df = new_df.groupBy().agg(collect_list("concat").as("aggregated"))
new_df.show

如果你想把数据变成一个字符串而不是数据框,你可以按如下方式收集它。

new_df.select("concat").collect.map(x=> x.get(0)).mkString("{", ",", "}")

【讨论】:

    【解决方案2】:

    由于您想将所有列转换为单个列,并且一开始的列似乎并不多,您可以将数据帧collect 到驱动程序并使用纯 Scala 代码将其转换为您想要的格式.

    下面会给你一个Array[String]

    val res = df.as[(String, Int)].collect.map{case(protocol, count) => protocol + ": " + count}
    

    要将其转换为单个字符串,只需执行以下操作:

    val str = res.mkString("{", ", ", "}")
    

    【讨论】:

      【解决方案3】:

      pivottoJSON 将为您提供所需的一切

      import org.apache.spark.sql.functions.first
      
      df.groupBy().pivot("protocol").agg(first("count")).toJSON.show(false)
      // +----------------------------------------------------------+                    
      // |value                                                     |
      // +----------------------------------------------------------+
      // |{"EGP":2331,"ICMP":7314,"IGMP":4423,"TCP":8321,"UDP":5523}|
      // +----------------------------------------------------------+
      

      【讨论】:

        猜你喜欢
        • 2017-01-07
        • 2020-11-10
        • 2015-08-11
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-06-09
        相关资源
        最近更新 更多