【问题标题】:How to convert arrays to map?如何将数组转换为地图?
【发布时间】:2019-06-11 02:36:28
【问题描述】:

我有一个像这样的 spark 数据框:

架构是: 我想要这样的最终结果: 即,在site_group 中创建_1: integer_2: map 之间的映射。

如何在 scala spark 中做到这一点?

【问题讨论】:

  • 能否添加文字而不是图片,方便用户复制和测试。

标签: scala apache-spark


【解决方案1】:

这是一种解决方案。首先让我们创建一些类似于您的示例数据,顺便说一句,如here 所讨论的那样,发布具有可重复输入和输出数据的问题会更有帮助。

val df = Seq(
(999, "2019-05-23", Seq((0,Map(2154 -> 0.545)))),
(511, "2019-06-30", Seq((1,Map(564654 -> 0.255699)))),
(322, "2019-02-10", Seq((2,Map(122 -> 0.896)))))
.toDF("user_id","dt", "site_group_collect")

// +-------+----------+---------------------------+
// |user_id|dt        |site_group_collect         |
// +-------+----------+---------------------------+
// |999    |2019-05-23|[[0, [2154 -> 0.545]]]     |
// |511    |2019-06-30|[[1, [564654 -> 0.255699]]]|
// |322    |2019-02-10|[[2, [122 -> 0.896]]]      |
// +-------+----------+---------------------------+

然后我们遍历每个项目并使用数据框的map 函数转换site_group_collect 的值:

df.map{case Row(uid: Int, dt: String, group: Seq[Row]) => 
     val transformed = group.map{ r => Map(r.getInt(0) -> r.get(1).asInstanceOf[Map[Int, Double]]) }
     (uid, dt, transformed)
}
.toDF("user_id","dt", "site_group_collect")
.show(false)

// +-------+----------+-----------------------------+
// |user_id|dt        |site_group_collect           |
// +-------+----------+-----------------------------+
// |999    |2019-05-23|[[0 -> [2154 -> 0.545]]]     |
// |511    |2019-06-30|[[1 -> [564654 -> 0.255699]]]|
// |322    |2019-02-10|[[2 -> [122 -> 0.896]]]      |
// +-------+----------+-----------------------------+

这里的关键点是将元组数组[[0, [2154 -> 0.545]]]表示为Rows的数组。另一种方法是将元组表示为case class,即:

case class Item(pk: Int, m: Map[Int, Double])

行:

val transformed = group.map{ r => Map(r.getInt(0) -> r.get(1).asInstanceOf[Map[Int, Double]]) }

将从现有元组中提取key/value 组合并将其分配给新创建的Map

一些相关的帖子:

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-06-29
    • 1970-01-01
    • 2017-07-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多