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

PySpark中如何从包含大小写不敏感属性的数据框中提取特定字典值

PySpark中如何从包含大小写不敏感属性的数据框中提取特定字典值

嗨,我看你现在遇到的问题是PySpark DataFrame里的字典键大小写不统一,比如Colour和colour混着出现,要提取特定值还得忽略大小写对吧?这确实是处理半结构化数据时很常见的小坑,我给你几个实用的解决办法,你可以根据自己的需求选~

先给大家还原下你的原始数据代码,方便对照:

dataDictionary = [
    ('value1', [{'key': 'Fruit', 'value': 'Apple'}, {'key': 'Colour', 'value': 'White'}]),
    ('value2', [{'key': 'Fruit', 'value': 'Mango'}, {'key': 'Bird', 'value': 'Eagle'}, {'key': 'Colour', 'value': 'Black'}]),
    ('value3', [{'key': 'Fruit', 'value': 'Apple'}, {'key': 'colour', 'value': 'Blue'}])
]   
df = spark.createDataFrame(data=dataDictionary)
df.printSchema()
df.show(truncate=False)

你的核心痛点是:DataFrame第二列的字典里,key值大小写混乱,直接用固定键名提取会漏掉数据,所以我们要实现大小写不敏感的键匹配。

方法一:自定义UDF(灵活易读,适合快速验证)

如果你习惯用Python逻辑来处理,写个UDF是最直观的思路。我们可以把所有键转成小写,再和目标键的小写形式匹配,不管原键是大写、小写还是混合,都能被识别到:

from pyspark.sql.functions import udf
from pyspark.sql.types import ArrayType, StructType, StructField, StringType

def extract_target_values(dict_list, target_keys):
    # 把目标键统一转成小写,避免大小写干扰
    target_lower = [k.lower() for k in target_keys]
    extracted_items = []
    for single_dict in dict_list:
        item = {}
        for k, v in single_dict.items():
            current_key_lower = k.lower()
            if current_key_lower in target_lower:
                # 结果用小写键统一命名,避免键名混乱
                item[current_key_lower] = v
        extracted_items.append(item)
    return extracted_items

# 注册UDF,指定返回类型:包含fruit和colour的结构体数组
extract_udf = udf(
    lambda x: extract_target_values(x, ['Fruit', 'Colour']),
    ArrayType(StructType([
        StructField('fruit', StringType(), nullable=True),
        StructField('colour', StringType(), nullable=True)
    ]))
)

# 应用UDF到DataFrame
result_df = df.withColumn('extracted_values', extract_udf('_2'))
result_df.select('_1', 'extracted_values').show(truncate=False)

这个UDF会遍历每个字典列表,把匹配到的键值对整理成结构统一的结果,你能清晰看到每个条目里的Fruit和Colour值,完全不受原键大小写的影响。

方法二:Spark内置函数(性能更优,适合大数据量)

如果你的数据量很大,UDF可能会拖慢性能,这时候用Spark的内置SQL表达式更合适——Spark能对内置函数做分布式优化,效率更高:

from pyspark.sql.functions import expr

# 先筛选出目标键值对,再拆分到单独列
result_df = df.withColumn(
    'processed_dicts',
    expr("""
        transform(
            _2,
            d -> map_from_entries(
                filter(
                    map_entries(d),
                    entry -> lower(entry.key) in ('fruit', 'colour')
                )
            )
        )
    """)
).withColumn(
    'fruit',
    expr("transform(processed_dicts, d -> d['fruit'])")
).withColumn(
    'colour',
    expr("transform(processed_dicts, d -> d['colour'])")
)

# 展示最终结果
result_df.select('_1', 'fruit', 'colour').show(truncate=False)

这里的逻辑很清晰:

  • 用map_entries把字典转成键值对结构体
  • 用filter+lower(entry.key)筛选出目标键(不区分大小写)
  • 用map_from_entries把筛选后的键值对转回字典
  • 最后用transform把对应值提取到单独列

如果你只需要提取单个值(比如只拿Fruit),还能简化成更短的表达式:

df.withColumn(
    'fruit_value',
    expr("""
        transform(
            _2,
            d -> element_at(
                filter(
                    map_values(map_from_entries(filter(map_entries(d), entry -> lower(entry.key) = 'fruit'))),
                    v -> v is not null
                ),
                1
            )
        )
    """)
).show(truncate=False)

备注:内容来源于stack exchange,提问作者Jim Macaulay

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.13 16:43:21