You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PySpark DataFrame将Array of Struct转为列(避免行重复)

解决方案

完全可以实现这种转换,不需要用explode拆分行。核心思路是把数组列转换成键值对Map,再从Map中提取对应字段的值,这样就能在原行基础上新增列,不会产生重复行。

步骤说明

  • 用map_from_entries函数将数组中的元素(每个元素是[id, value]的数组或struct)转换为Map类型,键是id,值是对应的value。
  • 对Map使用getItem方法提取"PHONE"、"FAX"、"MAIL"对应的值,自动处理不存在的键(返回null),同时兼容原数组为null的情况。

代码示例

首先创建示例DataFrame:

from pyspark.sql import SparkSession
from pyspark.sql.functions import map_from_entries, col

spark = SparkSession.builder.appName("array_to_columns").getOrCreate()

data = [
    (1, [["PHONE", "083665xxxx"], ["FAX", "0325xxxxxx"]]),
    (2, [["MAIL", "abc@xxx.com"]]),
    (3, None)
]

df = spark.createDataFrame(data, ["technical_id", "column_to_explode"])

执行转换逻辑:

# 转换数组为Map,处理null情况
df_transformed = df.withColumn(
    "contact_map",
    map_from_entries(col("column_to_explode"))
).select(
    "technical_id",
    "column_to_explode",
    col("contact_map").getItem("PHONE").alias("PHONE"),
    col("contact_map").getItem("FAX").alias("FAX"),
    col("contact_map").getItem("MAIL").alias("MAIL")
).drop("contact_map")

df_transformed.show()

输出结果

+-------------+--------------------+-----------+-----------+-------------+
|technical_id|    column_to_explode|      PHONE|        FAX|         MAIL|
+-------------+--------------------+-----------+-----------+-------------+
|            1|[["PHONE", "08366...|083665xxxx|0325xxxxxx|         null|
|            2|[["MAIL", "abc@xx...|       null|       null|abc@xxx.com|
|            3|                null|       null|       null|         null|
+-------------+--------------------+-----------+-----------+-------------+

适配原始struct结构的说明

如果你的原始数据结构是array of struct(即column_to_explode是包含id和value字段的struct数组),map_from_entries可以直接接收该类型,无需额外转换,代码逻辑和上述一致:

# 假设原始列是struct数组,结构为array<struct<id:string, value:string>>
df_transformed = df.withColumn(
    "contact_map",
    map_from_entries(col("column_to_explode"))
).select(
    "technical_id",
    "column_to_explode",
    col("contact_map").getItem("PHONE").alias("PHONE"),
    col("contact_map").getItem("FAX").alias("FAX"),
    col("contact_map").getItem("MAIL").alias("MAIL")
).drop("contact_map")

内容的提问来源于stack exchange,提问作者tpx

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.23 00:18:19