我有一个看起来像这样的Json文件
{
"tags": [
{
"1": "NpProgressBarTag",
"2": "userPath",
"3": "screen",
"4": 6,
"12": 9,
"13": "buttonName",
"16": 0,
"17": 10,
"18": 5,
"19": 6,
"20": 1,
"35": 1,
"36": 1,
"37": 4,
"38": 0,
"39": "npChannelGuid",
"40": "npShowGuid",
"41": "npCategoryGuid",
"42": "npEpisodeGuid",
"43": "npAodEpisodeGuid",
"44": "npVodEpisodeGuid",
"45": "npLiveEventGuid",
"46": "npTeamGuid",
"47": "npLeagueGuid",
"48": "npStatus",
"50": 0,
"52": "gupId",
"54": "deviceID",
"55": 1,
"56": 0,
"57": "uiVersion",
"58": 1,
"59": "deviceOS",
"60": 1,
"61": 0,
"62": "channelLineupID",
"63": 2,
"64": "userProfile",
"65": "sessionId",
"66": "hitId",
"67": "actionTime",
"68": "seekTo",
"69": "seekFrom",
"70": "currentPosition"
}
]
}
我尝试使用创建数据框
val path = "some/path/to/jsonFile.json"
val df = sqlContext.read.json(path)
df.show()
运行此命令我会得到
df: org.apache.spark.sql.DataFrame = [_corrupt_record: string]
我们如何基于“标签”键的内容创建df?我所需要做的就是从“标签”中提取数据并应用案例类
case class ProgLang (id: String, type: String )
我需要将此json数据转换为具有两个列名.toDF(id,Type)的数据帧 任何人都可以阐明这个错误吗?
答案 0 :(得分:0)
您可以使用Circe修改JSON。
鉴于您的值有时是 Strings ,有时是 Numbers ,所以这很复杂。
import io.circe._, io.circe.parser._, io.circe.generic.semiauto._
val json = """ ... """ // your JSON here.
val doc = parse(json).right.get
val mappedDoc = doc.hcursor.downField("tags").withFocus { array =>
array.mapArray { jsons =>
jsons.map { json =>
json.mapObject { o =>
o.mapValues { v =>
// Cast numbers to strings.
if (v.isString) v else Json.fromString(v.asNumber.get.toString)
}
}
}
}
}
final case class ProgLang(id: String, `type`: String )
final case class Tags(tags: List[Map[String, String]])
implicit val TagsDecoder: Decoder[Tags] = deriveDecoder
val tags = mappedDoc.top.get.as[Tags]
val data = for {
tag <- res29.tags
(id, _type) <- tag
} yield ProgLang(id, _type)
现在您有了ProgLang
的列表,可以直接从中创建一个DataFrame
,将其保存为文件,每行每个 JSON ,将其保存为< strong> CSV 文件等...
如果文件很大,可以在转换时使用fs2进行流式传输,通过 Circe 可以很好地integrates。
免责声明::我远不是Circe的“专业人士”,这似乎让做“简单任务”的事情变得过于复杂,也许还有更好的选择/更清洁的方式(也许使用光学元件?),但是嘿!有用! -无论如何,如果有人知道解决此问题的更好方法,请随时编辑问题或提供您的问题。
答案 1 :(得分:0)
val path = "some/path/to/jsonFile.json"
spark.read
.option("multiLine", true).option("mode", "PERMISSIVE")
.json(path)
答案 2 :(得分:0)
如果您的json文件不是很大,请尝试以下代码
val spark = SparkSession.builder().getOrCreate()
val df = spark.read.json(spark.sparkContext.wholeTextFiles("some/path/to/jsonFile.json").values)