PySpark:如何从Struct数组列中按前缀条件提取元素值
问题:Spark DataFrame按Key前缀提取对应Value值
数据结构与样本数据
DataFrame Schema
|-- col1 : string |-- col2 : string |-- customer: struct | |-- smt: string | |-- attributes: array (nullable = true) | | |-- element: struct | | | |-- key: string | | | |-- value: string
样本数据
| col1 | col2 | customer |
|---|---|---|
| col1_XX | col2_XX | {"attributes": [{"key": "AUS 1", "value": "56"},{"key":"BS 1", "value": "45"}]} |
需求与问题
需要提取customer.attributes中key以"A"开头的对应value值,尝试了以下代码但返回null:
df = df.withColumn('AUS',expr("filter(customer.attributes,x->x.key='AUS')")[0]["value"])
期望输出
| col1 | col2 | customer | AUS |
|---|---|---|---|
| col1_XX | col2_XX | {"attributes": [{"key": "AUS 1", "value": "56"},{"key":"BS 1", "value": "45"}]} | 56 |
实际输出
| col1 | col2 | customer | AUS |
|---|---|---|---|
| col1_XX | col2_XX | {"attributes": [{"key": "AUS 1", "value": "56"},{"key":"BS 1", "value": "45"}]} | null |
解决方案
原代码用精确匹配x.key='AUS',但实际key是"AUS 1",需改用前缀匹配,以下两种方式均可实现需求:
方法1:使用starts_with函数(性能更优,适合简单前缀匹配)
from pyspark.sql import functions as F df = df.withColumn( 'AUS', F.expr("filter(customer.attributes, x -> starts_with(x.key, 'A'))")[0]["value"] )
方法2:使用正则匹配rlike(适合复杂匹配规则)
如果需要匹配以"AUS"开头的key,可使用正则表达式:
df = df.withColumn( 'AUS', F.expr("filter(customer.attributes, x -> x.key rlike '^AUS')")[0]["value"] )
补充:处理无匹配项的场景
如果存在没有符合条件key的情况,可结合coalesce和element_at避免异常或返回指定默认值:
df = df.withColumn( 'AUS', F.coalesce( F.element_at(F.expr("filter(customer.attributes, x -> starts_with(x.key, 'A'))"), 1)["value"], F.lit(None) # 可替换为你需要的默认值,比如F.lit("无匹配") ) )
内容的提问来源于stack exchange,提问作者Pranoy Mukherjee
相关产品推荐
相关产品推荐

