PySpark中如何从struct数组提取字段生成属性名与值列
解决方案
首先明确核心问题:你需要将struct数组字段atributos展开为属性名和属性值两列,同时保留原DataFrame的其他字段。以下分两种常见场景给出实现代码:
场景1:atributos是包含name和value字段的struct数组
如果你的atributos数组中每个元素是形如struct<name:string, value:int>的结构体(即每个元素直接存储属性名和对应值),可以直接展开数组后提取字段:
from pyspark.sql.functions import explode # 展开atributos数组,生成临时列atributo df_exploded = df.withColumn("atributo", explode("atributos")) # 提取属性名和值,保留所有原字段 df_result = df_exploded.select( "*", df_exploded.atributo.name.alias("name_of_atribute"), df_exploded.atributo.value.alias("value_of_atribute") ).drop("atributo")
场景2:atributos数组中的每个struct包含多个属性字段
如果atributos数组的每个元素是包含多个属性的struct(比如struct<bikes:int, bags:int, suitcases:int>),需要先将struct转为键值对Map,再展开Map得到属性名和值:
from pyspark.sql.functions import explode, map_entries, to_map # 先展开数组,再将每个struct转为Map并拆分为键值对 df_result = df.withColumn("atributo", explode("atributos")) \ .withColumn("attr_kv", explode(map_entries(to_map("atributo")))) \ .select( "*", df.attr_kv.key.alias("name_of_atribute"), df.attr_kv.value.alias("value_of_atribute") ).drop("atributo", "attr_kv")
你原有代码的问题
df2 = df.explode("atributos").alias("atributo")的写法不符合PySpark API规范:
- PySpark中
explode需要通过withColumn添加新列,而非直接链式调用在DataFrame上 - 仅展开数组但未提取struct内部的字段,因此无法得到属性名和值的独立列
内容的提问来源于stack exchange,提问作者tempo
相关产品推荐
相关产品推荐

