我正在尝试转换以下架构:
|-- a: struct (nullable = true)
| |-- b: struct (nullable = true)
| | |-- one: double (nullable = true)
| | |-- two: array (nullable = true)
| | | |-- element: string (containsNull = true)
| | |-- three: string (nullable = true)
| | |-- four: boolean (nullable = true)
| |-- c: struct (nullable = true)
| | |-- one: double (nullable = true)
| | |-- two: array (nullable = true)
| | | |-- element: string (containsNull = true)
| | |-- three: string (nullable = true)
| | |-- four: boolean (nullable = true)
变成这样:
|-- a: array (nullable = true)
| |-- element: struct (containsNull = true)
| | |-- struct_key: string (nullable = true)
| | |-- one: double (nullable = true)
| | |-- two: array (nullable = true)
| | | |-- element: string (containsNull = true)
| | |-- three: string (nullable = true)
| | |-- four: boolean (nullable = true)
| |-- element: struct (containsNull = true)
| | |-- struct_key: string (nullable = true)
| | |-- one: double (nullable = true)
| | |-- two: array (nullable = true)
| | | |-- element: string (containsNull = true)
| | |-- three: string (nullable = true)
| | |-- four: boolean (nullable = true)
实际上只是尝试获取结构键,并将其转换为字符串,然后将其添加到列中。数据集中的b
/c
结构体很多,因此需要一些通配符来转换它们。
我用的是Spark 3.2.1。
数据是从JSON生成的,因此读取如下:
df = spark.read.json(json_file)
2条答案
按热度按时间4c8rllxm1#
我更喜欢这种方法,因为我们经常需要保留原始 Dataframe 中存在的其他列。
df.schema['a'].dataType[0].dataType.simpleString()
导航到内部结构并以DDL格式提取其架构。F.from_json(F.to_json("a"), f'map<string,{dtype}>')
将内部的 struct 转换为 map。struct的字段名成为map的键,而struct本身成为map的值。这种转换非常有用,因为它使访问字段名变得更容易。F.transform_values(..., lambda k, v: v.withField('struct_key', k))
将map的键添加到map的值中(即添加到结构体中)。F.map_values()
提取Map的值,从而生成一个结构数组。测试输入:
结果:
l5tcr1uw2#
下面是一种方法,首先在内部结构体中添加
struct_key
,然后使用它们创建一个数组。