PySpark:如何将嵌套结构中的字符串列转换为结构体
问题描述
我有如下数据Schema:
|--items : array |-- element : struct |-- id : long |-- value : double |-- stock : array |-- element : string
想使用withColumn访问stock列,把它转换成结构体数组,目标输出Schema如下:
|--items : array |-- element : struct |-- id : long |-- value : double |-- stock : array |-- element : struct |-- id : long |-- val : double
我尝试了以下代码但没成功:
df = df.withColumn( ‘items’, F.col(‘items’).withField( ‘stock’, F.structure( F.lit(None).cast(‘long’).alias(‘id’), F.lit(None).cast(‘double’).alias(‘val’) ) ) )
解决方案
你原来的代码问题有两个:一是直接给stock字段赋值了单个结构体,没处理数组里的每一个元素;二是用了中文引号,会导致语法错误,要换成英文引号。
根据需求分两种情况处理:
情况1:stock中的string需要解析成id和val
如果stock数组里的字符串是可以拆分的格式(比如"1,3.14"这种逗号分隔的),可以用split解析后转成对应类型:
import pyspark.sql.functions as F df = df.withColumn( "items", F.transform( "items", lambda item: item.withField( "stock", F.transform( item["stock"], lambda s: F.struct( F.split(s, ",")[0].cast("long").alias("id"), F.split(s, ",")[1].cast("double").alias("val") ) ) ) ) )
情况2:stock中的string不需要解析,直接转成空值结构体
如果只是要把每个string元素换成包含空值的结构体,直接用lit(None)赋值即可:
import pyspark.sql.functions as F df = df.withColumn( "items", F.transform( "items", lambda item: item.withField( "stock", F.transform( item["stock"], lambda _: F.struct( F.lit(None).cast("long").alias("id"), F.lit(None).cast("double").alias("val") ) ) ) ) )
逻辑说明
- 外层
transform遍历items数组里的每一个结构体元素; - 用
withField修改每个item里的stock字段; - 内层
transform遍历stock数组的每一个string元素,把单个元素转换成目标结构体。
内容的提问来源于stack exchange,提问作者OdiumPura
相关产品推荐
相关产品推荐

