json - Scala 对象、数据集和数据框之间的链接
问题描述
我创建了以下案例类:
case class Data(ads:Option[Ads])
case class Ads(subject: Option[String]
, body:Option[String]
, price:Option[Int]
, location:Option[Location]
, attribut:Option[Seq[Attribut]]
)
case class Location(city:Option[String]
, zipcode:Option[String])
case class Attribut(key_label:Option[String]
, value_label:Option[String]
)
我使用播放框架解析 JSON 格式(HTML 的一部分)。
我终于得到了一个对象广告
JsSuccess(Ads(Some("Subject"), SOme("Body"), Some(Price), Some(Location(Some("City"), Some("Zipcode")), Some(Attribut("key_label", "value_label"))
我想通过以下方式将其保存在 CSV 文件中:
Subject Body Price City Zipcode Key_Label Value_Label
Play Playing games 532 Geneve 95 GEN Gen2
我将对象转换为 List ofAds(Some("Subject"), Some("Body"), Some(Price), Some(Location(Some("City"), Some("Zipcode")), Some(Attribut("key_label", "value_label")
并将此列表转换为 DataFrame。
但我只有一列 Value 包含对象的所有元素。
Value
(Some("Subject"), SOme("Body"), Some(Price), Some(Location(Some("City"), Some("Zipcode")), Some(Attribut("key_label", "value_label")
有人有想法吗?我真的不明白如何将 scala 对象与数据集和数据框链接起来。谢谢您的帮助。
解决方案
注释很有帮助,但通用展平功能可能不会以所需的顺序输出列,和/或处理将数组元素放入它们自己的单独列中。
假设您的 JSON 文件包含以下行:
{"ads": {"subject": "abc", "body": "doing something", "price": 13, "location": {"city": "Houston", "zipcode": 39014}, "attribut": [{"key_label": "a", "value_label": "b"}]}}
如果文件相当一致并且您已经将 Spark 作为依赖项包含在内,则您可能不需要使用单独的库来解析 JSON。
您将需要使用该explode
函数来处理“属性”列是一个列表的事实。explode_outer
如果列表可能为空但您想保留其他列的值,请改用该函数。
import org.apache.spark.sql.functions._
// assuming spark is the Spark Session
val df = spark.read.json("mydata.json")
val df1 = df.select(col("ads.subject").alias("Subject"), col("ads.body").alias("Body"),
col("ads.location.city").alias("City"), col("ads.location.zipcode").alias("Zipcode"),
explode(col("ads.attribut")))
val resultDF = df1.select(col("Subject"), col("Body"), col("City"), col("Zipcode"),
col("col.key_label"), col("col.value_label"))
resultDF.show
会输出:
+-------+---------------+-------+-------+---------+-----------+
|Subject| Body| City|Zipcode|key_label|value_label|
+-------+---------------+-------+-------+---------+-----------+
| abc|doing something|Houston| 39014| a| b|
+-------+---------------+-------+-------+---------+-----------+
输出为指定目录中的单个 CSV 文件,带有标题:
resultDF.repartition(1).write.option("header", "true").csv("/tmp/my-output-dir/")
推荐阅读
- python - seaborn 传奇标题位置
- java - player.sendMessage 发送两次
- css - 将“rem”与“vw”结合用于灵活的网站
- r - 为函数调用提供多个名称
- dialog - 我可以使用 BlueSky Statistics 创建新的自定义对话框吗?
- r - 长到宽,每个组/ID 的行数不同
- css - 角材料不加载
- nsis - 如何使用 NSIS 检查 Visual C++ 2017 可再发行 x86 是否已安装
- javascript - A-Frame "mouseenter" 在 VR 模式下不起作用
- firebase - Firebase 托管 - 如何防止标准域导致内容重复?