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

在Databricks中用PySpark将字符串列拆分生成新列的需求

PySpark实现嵌套数组结构体转列方案

针对你的需求,这里提供两种高效的PySpark实现方式,直接将data列中每个字典的fname转为独立列,取值对应value,最终删除原data列。

方法一:利用聚合构建Map后提取列(性能优先,适合固定fname场景)

这种方法无需拆分数据行,直接在原行内将数组转为键值对Map,再提取对应列,性能更优。

from pyspark.sql import functions as F

# 假设你的DataFrame名为df,先确认data列是ArrayType(StructType)
# 如果data列是字符串格式,先解析为结构体数组(如果已正确识别可跳过)
# json_schema = F.ArrayType(F.StructType([F.StructField("fname", F.StringType()), F.StructField("value", F.DoubleType())]))
# df = df.withColumn("data", F.from_json(F.to_json("data"), json_schema))

# 将data数组转为{fname: value}的Map
df_with_map = df.withColumn(
    "data_map",
    F.aggregate(
        F.col("data"),
        F.lit({}),
        lambda acc, item: F.map_concat(acc, F.create_map(item["fname"], item["value"]))
    )
)

# 提取每个fname对应的列,删除原data列和中间map列
df_final = df_with_map \
    .withColumn("name1", F.col("data_map").getItem("name1")) \
    .withColumn("name2", F.col("data_map").getItem("name2")) \
    .withColumn("name3", F.col("data_map").getItem("name3")) \
    .withColumn("name4", F.col("data_map").getItem("name4")) \
    .drop("data", "data_map")

# 查看结果
df_final.show(truncate=False)

方法二:Explode+Pivot(灵活适配动态fname)

如果data列中的fname不固定(可能新增其他名称),可以用拆分后透视的方式,自动识别所有fname转为列。

from pyspark.sql import functions as F

# 拆分data数组,将每个结构体转为单独行
df_exploded = df.withColumn("data_item", F.explode("data"))

# 提取fname和value字段,按主列分组后透视转列
df_final = df_exploded \
    .select("ida", "ids", "mode", F.col("data_item.fname"), F.col("data_item.value")) \
    .groupBy("ida", "ids", "mode") \
    .pivot("fname") \
    .agg(F.first("value"))

# 查看结果
df_final.show(truncate=False)

关键说明

  • 若data列存储的是字符串格式的数组而非结构化数据,需先用from_json解析为ArrayType(StructType),代码注释中已给出示例。
  • 方法一适合fname固定的场景,避免数据膨胀,性能更优;方法二适合fname动态变化的场景,自动适配所有可能的名称。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.14 18:28:35