gpt4 book ai didi

scala - 将映射键分解为列名

转载 作者:行者123 更新时间:2023-12-05 05:09:24 28 4
gpt4 key购买 nike

我已经为此苦苦挣扎了一段时间,无法解决这个问题。到目前为止,我只找到了 explode() 的例子一个MapType列到 n行条目。

我想要实现的是,例如,在同一行中有 5 个条目作为 5 列的 Map。

以这个DF为例...

case class SampleRow(one: String, two: String, three: String, four: String, five: Map[String, String])       
val df = List(
SampleRow(
"one",
"two",
"three",
"four",
Map("sample_one" -> "hey", "sample_two" -> "hey"))
).toDF()

展开列后five ,它应该变成

<表类="s-表"><头><日>一 两个三<日>四 sample_onesample_two<正文>一个两个三个四个嘿嘿嘿嘿

到目前为止,我尝试的是以下内容。

val explodedDS = originDS
.select(cols :+ $"key".as("outerMap") :+ $"value.*":_*) // Column 'value' as a previous Map has been exploded before

但是这样做会在控制台中提示以下错误。

Exception in thread "main" org.apache.spark.sql.AnalysisException: Can only star expand struct data types. Attribute: ArrayBuffer(value);

我知道将 Map 分解为 Columns 会产生无法推断架构的问题,直到所有 Row 对象都包含完全相同数量的 Columns,要么为 null 要么有一个值,对吧?

但除此之外,尽管存在模式问题,是否还有其他选择可以实现这一点?

最佳答案

这可能不是最快的,但似乎可行:

import org.apache.spark.sql.{Encoder, Encoders}
import org.apache.spark.sql.functions._
import spark.implicits._

case class SampleRow(one: String, two: String, three: String, four: String, five: Map[String, String])
implicit def enc: Encoder[SampleRow] = Encoders.product[SampleRow]

val df = spark.createDataset(List(
SampleRow(
"one",
"two",
"three",
"four",
Map("sample_one" -> "hey", "sample_two" -> "hey"))
))

df.select($"*", explode($"five"))
.groupBy("one", "two", "three", "four")
.pivot("key")
.agg(first($"value"))
.show()

这会产生所需的输出:

+---+---+-----+----+----------+----------+
|one|two|three|four|sample_one|sample_two|
+---+---+-----+----+----------+----------+
|one|two|three|four| hey| hey|
+---+---+-----+----+----------+----------+

这可能无法完全概括您的实际用例,但它应该足够接近以使其可行。

关于scala - 将映射键分解为列名,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57593428/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com