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

PySpark:如何将指定列转为含列名key的结构体数组

Spark中生成包含列名作为Key的结构体数组

问题根源

你之前的写法存在两个核心问题:

  1. TRANSFORM(array(name, age), col -> ...) 里的 array(name, age) 生成的是列值的数组,没有携带列名元信息,迭代过程中无法获取原列名。
  2. 使用f-string的{col}时,Python会优先尝试解析本地变量col,但col是SQL表达式内的迭代变量,Python上下文不存在该变量,因此抛出NameError。

正确实现方式

1. 固定列名场景

直接为每个目标列构造包含列名字面量和对应值的结构体,再将这些结构体组合成数组:

df_with_column_of_structs = df.withColumn(
    'array_of_structs',
    expr("array(named_struct('key', 'name', 'val', name), named_struct('key', 'age', 'val', age))")
)

2. 动态传入列名字符串列表场景

如果需要通过列名列表(比如cols = ['name', 'age'])动态生成,可通过字符串拼接构造SQL表达式:

cols = ['name', 'age']
# 生成每个列对应的named_struct语句
struct_exprs = [f"named_struct('key', '{col}', 'val', {col})" for col in cols]
# 组合成完整的array表达式
array_expr = f"array({','.join(struct_exprs)})"

df_with_column_of_structs = df.withColumn('array_of_structs', expr(array_expr))

验证输出

执行上述代码后,show()的输出将符合预期:

+-------+---+-----------+---------------------------+
|name   |age|city       |array_of_structs           |
+-------+---+-----------+---------------------------+
|Alice  |30 |New York   |[{name, Alice}, {age, 30}]  |
|Bob    |25 |Los Angeles|[{name, Bob}, {age, 25}]    |
|Charlie|35 |Chicago    |[{name, Charlie}, {age, 35}]|
+-------+---+-----------+---------------------------+

补充:TRANSFORM的冗余写法

如果一定要使用TRANSFORM,需要先构造包含列名和值的配对数组,再迭代生成结构体(此方式灵活性不如上述方案):

df_with_column_of_structs = df.withColumn(
    'array_of_structs',
    expr("TRANSFORM(array((name, 'name'), (age, 'age')), x -> named_struct('key', x._2, 'val', x._1))")
)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.26 09:42:43