将 python 字典转换为 pyspark 数据框
convert python dictionary into pyspark dataframe
我有一个 json 文件,其中包含以下格式的字典:
{"a1":{"b1":["c1","c2"], "b2":["c4","c3"]}, "a2":{"b3":["c1","c4"]}}
是否可以将此字典转换为 PySpark 数据框,如下所示?
col1 | col2 | col3
----------------------
| a1 | b1 | c1 |
----------------------
| a1 | b1 | c2 |
----------------------
| a1 | b2 | c4 |
----------------------
| a1 | b2 | c3 |
----------------------
| a2 | b3 | c1 |
----------------------
| a2 | b3 | c4 |
我已经看到将 json 转换为 PySpark 数据帧的标准格式(此 link 中的示例),但想知道是否也包含列表的嵌套字典。
有趣的问题!我意识到这个问题的主要困难是你从 JSON 读取时,你的模式可能具有结构类型,这使得它更难解决,因为基本上 a1
的类型与 a2
不同。
我的想法是以某种方式将结构类型转换为映射类型,然后将它们堆叠在一起,然后应用一些 explode
s:
这是你的df
+----------------------------------+
|data |
+----------------------------------+
|{{[c1, c2], [c4, c3]}, {[c1, c4]}}|
+----------------------------------+
root
|-- data: struct (nullable = true)
| |-- a1: struct (nullable = true)
| | |-- b1: array (nullable = true)
| | | |-- element: string (containsNull = true)
| | |-- b2: array (nullable = true)
| | | |-- element: string (containsNull = true)
| |-- a2: struct (nullable = true)
| | |-- b3: array (nullable = true)
| | | |-- element: string (containsNull = true)
创建一个临时 df 来处理 JSON 的第一关
first_level_df = df.select('data.*')
first_level_df.show()
first_level_cols = first_level_df.columns # ['a1', 'a2']
+--------------------+----------+
| a1| a2|
+--------------------+----------+
|{[c1, c2], [c4, c3]}|{[c1, c4]}|
+--------------------+----------+
一些辅助变量
map_cols = [F.from_json(F.to_json(c), T.MapType(T.StringType(), T.StringType())).alias(c) for c in first_level_cols]
# [Column<'entries AS a1'>, Column<'entries AS a2'>]
stack_cols = ', '.join([f"'{c}', {c}" for c in first_level_cols])
# 'a1', a1, 'a2', a2
主要改造
(first_level_df
.select(map_cols)
.select(F.expr(f'stack(2, {stack_cols})').alias('AA', 'temp'))
.select('AA', F.explode('temp').alias('BB', 'temp'))
.select('AA', 'BB', F.explode(F.from_json('temp', T.ArrayType(T.StringType()))).alias('CC'))
.show(10, False)
)
+---+---+---+
|AA |BB |CC |
+---+---+---+
|a1 |b1 |c1 |
|a1 |b1 |c2 |
|a1 |b2 |c4 |
|a1 |b2 |c3 |
|a2 |b3 |c1 |
|a2 |b3 |c4 |
+---+---+---+
我有一个 json 文件,其中包含以下格式的字典:
{"a1":{"b1":["c1","c2"], "b2":["c4","c3"]}, "a2":{"b3":["c1","c4"]}}
是否可以将此字典转换为 PySpark 数据框,如下所示?
col1 | col2 | col3
----------------------
| a1 | b1 | c1 |
----------------------
| a1 | b1 | c2 |
----------------------
| a1 | b2 | c4 |
----------------------
| a1 | b2 | c3 |
----------------------
| a2 | b3 | c1 |
----------------------
| a2 | b3 | c4 |
我已经看到将 json 转换为 PySpark 数据帧的标准格式(此 link 中的示例),但想知道是否也包含列表的嵌套字典。
有趣的问题!我意识到这个问题的主要困难是你从 JSON 读取时,你的模式可能具有结构类型,这使得它更难解决,因为基本上 a1
的类型与 a2
不同。
我的想法是以某种方式将结构类型转换为映射类型,然后将它们堆叠在一起,然后应用一些 explode
s:
这是你的df
+----------------------------------+
|data |
+----------------------------------+
|{{[c1, c2], [c4, c3]}, {[c1, c4]}}|
+----------------------------------+
root
|-- data: struct (nullable = true)
| |-- a1: struct (nullable = true)
| | |-- b1: array (nullable = true)
| | | |-- element: string (containsNull = true)
| | |-- b2: array (nullable = true)
| | | |-- element: string (containsNull = true)
| |-- a2: struct (nullable = true)
| | |-- b3: array (nullable = true)
| | | |-- element: string (containsNull = true)
创建一个临时 df 来处理 JSON 的第一关
first_level_df = df.select('data.*')
first_level_df.show()
first_level_cols = first_level_df.columns # ['a1', 'a2']
+--------------------+----------+
| a1| a2|
+--------------------+----------+
|{[c1, c2], [c4, c3]}|{[c1, c4]}|
+--------------------+----------+
一些辅助变量
map_cols = [F.from_json(F.to_json(c), T.MapType(T.StringType(), T.StringType())).alias(c) for c in first_level_cols]
# [Column<'entries AS a1'>, Column<'entries AS a2'>]
stack_cols = ', '.join([f"'{c}', {c}" for c in first_level_cols])
# 'a1', a1, 'a2', a2
主要改造
(first_level_df
.select(map_cols)
.select(F.expr(f'stack(2, {stack_cols})').alias('AA', 'temp'))
.select('AA', F.explode('temp').alias('BB', 'temp'))
.select('AA', 'BB', F.explode(F.from_json('temp', T.ArrayType(T.StringType()))).alias('CC'))
.show(10, False)
)
+---+---+---+
|AA |BB |CC |
+---+---+---+
|a1 |b1 |c1 |
|a1 |b1 |c2 |
|a1 |b2 |c4 |
|a1 |b2 |c3 |
|a2 |b3 |c1 |
|a2 |b3 |c4 |
+---+---+---+