【问题标题】:Reading complex nested json file in pyspark在pyspark中读取复杂的嵌套json文件
【发布时间】:2021-09-28 06:49:40
【问题描述】:

我这几天都在尝试解决这个问题。

我有一个嵌套的 json 文件,它具有复杂的架构(结构内的数组,数组内的结构),我需要将数据放入数据框中。

我的输入是这样的(例如):

+-----+----------------+-----------------------------------+---------+
| id  | name           | detail                            | item    |
+-----+----------------+-----------------------------------+---------+
| 100 | Peter Castle   | [[D100A, Credit],[D100B, Debit]]  | [10,31] |
| 101 | Quino Yukimori | [[D101A, Credit],[D101B, Credit]] | [55,49] |
+-----+----------------+-----------------------------------+---------+

我应该这样读

+-----+----------------+-----------+--------+-----------+
| id  | name           | detail_id | type   | item_qty  |
+-----+----------------+-----------+--------+-----------+
| 100 | Peter Castle   | D100A     | Credit | 10        |
| 100 | Peter Castle   | D100B     | Debit  | 31        |
| 101 | Quino Yukimori | D101A     | Credit | 55        |
| 101 | Quino Yukimori | D101B     | Credit | 49        |
+-----+----------------+-----------+--------+-----------+

但我得到的是:


df.withColumn('detail', explode('detail')).withColumn('item', explode('item'))

+-----+----------------+-----------+--------+-----------+
| id  | name           | detail_id | type   |  item_qty |
+-----+----------------+-----------+--------+-----------+
| 100 | Peter Castle   | D100A     | Credit | 10        |
| 100 | Peter Castle   | D100A     | Debit  | 10        |
| 100 | Peter Castle   | D100B     | Credit | 31        |
| 100 | Peter Castle   | D100B     | Debit  | 31        |
| 101 | Quino Yukimori | D101A     | Credit | 55        |
| 101 | Quino Yukimori | D101A     | Credit | 55        |
| 101 | Quino Yukimori | D101B     | Credit | 49        |
| 101 | Quino Yukimori | D101B     | Credit | 49        |
+-----+----------------+-----------+--------+-----------+

我曾尝试将列与arrays_zip合并然后分解,但问题是数组内部有数组,如果我分解详细数组列,项目数组列的分解会乘以数据。

知道如何实现吗?

对不起,我的英语不是我的母语。

已更新

这是我的架构,这让我在阅读多个嵌套数组时变得复杂:

 |-- id: string(nullable = true)
 |-- name: string(nullable = true)
 |-- detail: array (nullable = true)
 |   |-- element: struct (containsNull = true)
 |   |    |-- detail_id: string(nullable = true)
 |   |    |-- type: string(nullable = true)
 |-- item: array (nullable = true)
 |   |-- element: struct (containsNull = true)
 |   |    |-- item_qty : long(nullable = true)
 |-- deliveryTrack: array (nullable = true)
 |   |-- element: struct (containsNull = true)
 |   |    |-- date: string(nullable = true)
 |   |    |-- track: array (nullable = true)
 |   |    |   |-- element: struct (containsNull = true)
 |   |    |   |   |-- time: string (nullable = true)
 |   |    |   |   |-- driver: string (nullable = true)

【问题讨论】:

  • 同时发布为您提供该输出的代码

标签: arrays json pyspark nested explode


【解决方案1】:

在使用arrays_zip 压缩两个数组后,仅一次使用explode。之后,使用expr函数获取数据。

from pyspark.sql.functions import explode, arrays_zip, col, expr

df1 = (df
      .withColumn('buffer', explode(arrays_zip(col('detail'), col('item'))))
      .withColumn('detail_id', expr("buffer.detail.detail_id"))
      .withColumn('type', expr("buffer.detail.type"))
      .withColumn('item_qty', expr("buffer.item.item_qty"))
      .drop(*['detail', 'item', 'buffer'])
    )
df1.show()

+---+--------------+---------+------+--------+
|id |name          |detail_id|type  |item_qty|
+---+--------------+---------+------+--------+
|100|Peter Castle  |D100A    |Credit|10      |
|100|Peter Castle  |D100B    |Debit |31      |
|101|Quino Yukimori|D101A    |Credit|55      |
|101|Quino Yukimori|D101B    |Credit|49      |
+---+--------------+---------+------+--------+

【讨论】:

  • 您好,感谢您帮助我。我已经尝试过您的解决方案但收到此错误:AnalysisException: cannot resolve 'element_at(buffer.detail, 1)' due to data type mismatch: The first argument to function element_at should have been array or map type, but its struct...
  • 我已经更新了我的问题,添加了架构以便更好地理解
  • 试图复制你的架构,我已经编辑了我的答案。
  • 嘿,它有效!非常感谢 - 但是如果需要获取位于 DeliveryTrack 数组中的时间和驱动程序列,我该怎么办?你能帮我吗?因为虽然我必须阅读更多的数组,但也会出现同样的问题。但是,您回答了我最初的问题,这就是我标记为已回答的原因。
  • 您可以在arrays_zip 中包含列deliveryTrack,然后稍后使用嵌套列名称(如"buffer.deliveryTrack.track.driver")访问数据
猜你喜欢
  • 2020-01-08
  • 1970-01-01
  • 2021-02-02
  • 1970-01-01
  • 2019-10-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多