簡體   English   中英

將 JSON 讀入火花 dataframe

[英]Reading JSON into spark dataframe

我正在學習 Spark,並且正在構建一個示例項目。 我有一個火花 dataframe 它具有以下語法。 此語法是當我將 dataframe 保存到 JSON 文件時:

{"str":["1001","19035004":{"Name":"Chris","Age":"29","Location":"USA"}]}
{"str":["1002","19035005":{"Name":"John","Age":"20","Location":"France"}]}
{"str":["1003","19035006":{"Name":"Mark","Age":"30","Location":"UK"}]}
{"str":["1004","19035007":{"Name":"Mary","Age":"22","Location":"UK"}]}

JSONInput.show() 給了我如下內容:

+---------------------------------------------------------------------+
|str                                                                  |
+---------------------------------------------------------------------+
|[1001,{"19035004":{"Name":"Chris","Age":"29","Location":"USA"}}]     |
|[1002,{"19035005":{"Name":"John","Age":"20","Location":"France"}}]   |
|[1003,{"19035006":{"Name":"Mark","Age":"30","Location":"UK"}}]       |
|[1004,{"19035007":{"Name":"Mary","Age":"22","Location":"UK"}}]       |
+---------------------------------------------------------------------|

我知道這不是 JSON 的正確語法,但這就是我所擁有的。

首先,我如何才能在關系結構中得到它(因為我對 JSON 和 Spark 很陌生。所以這不是強制性的):

Name    Age   Location
-----------------------
Chris   29    USA
John    20    France
Mark    30    UK
Mary    22    UK

我想過濾特定國家:

val resultToReturn = JSONInput.filter("Location=USA")

但這會導致以下錯誤:

線程“主”org.apache.spark.sql.AnalysisException 中的異常:無法解析給定輸入列的Location :[str]; 第 1 行第 0 行;

如何擺脫“str”並使數據采用適當的 JSON 結構? 任何人都可以幫忙嗎?

您可以使用from_json解析字符串值:

import org.apache.spark.sql.types._

val schema = MapType(StringType,
  StructType(Array(
      StructField("Name", StringType, true),
      StructField("Age", StringType, true),
      StructField("Location", StringType, true)
    )
  ), true
)

val resultToReturn = JSONInput.select(
    explode(from_json(col("str")(1), schema))
  ).select("value.*")

resultToReturn.show
//+-----+---+--------+
//| Name|Age|Location|
//+-----+---+--------+
//|Chris| 29|     USA|
//| John| 20|  France|
//| Mark| 30|      UK|
//| Mary| 22|      UK|
//+-----+---+--------+

然后你可以過濾:

resultToReturn.filter("Location = 'USA'").show
//+-----+---+--------+
//| Name|Age|Location|
//+-----+---+--------+
//|Chris| 29|     USA|
//+-----+---+--------+

您可以使用 regexp_extract 提取最里面的 JSON 並使用regexp_extract解析該from_json 然后您可以對提取的 JSON 結構進行星型擴展。

val parsed_df = JSONInput.selectExpr("""
    from_json(
        regexp_extract(str[0], '(\\{[^{}]+\\})', 1),
        'Name string, Age string, Location string'
    ) as parsed
""").select("parsed.*")

parsed_df.show(false)
+-----+---+--------+
|Name |Age|Location|
+-----+---+--------+
|Chris|29 |USA     |
|John |20 |France  |
|Mark |30 |UK      |
|Mary |22 |UK      |
+-----+---+--------+

你可以使用過濾它

val filtered = parsed_df.filter("Location = 'USA'")

PS記得在美國周圍加上單引號。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM