为何从Spark map列提取值的pandas_udf报DataFrame无map属性错误
报错原因
你编写的pandas UDF报错的核心原因是输入列的类型映射不符合PySpark的pandas UDF规则:
- 你传入的
country列是Spark的StructType结构体类型,并非单值类型。根据PySpark的pandas UDF参数映射规则,StructType类型的列传入pandas UDF时,会被自动转换为pandas DataFrame,每个结构体的字段对应DataFrame的一列,而非你预期的每个元素为字典的pd.Series。 - 你在函数签名中声明参数为
pd.Series,但实际收到的是pd.DataFrame对象,调用只有Series才有的map方法,自然触发'DataFrame' object has no attribute 'map'的报错。
修复方案
如果要保留pandas UDF的实现,有两种常用修改方式:
方案1:直接处理传入的DataFrame
直接读取Struct映射生成的DataFrame的context列即可:
from pyspark.sql.functions import pandas_udf, col import pandas as pd @pandas_udf("string") def get_country_context(country_df: pd.DataFrame) -> pd.Series: # 直接取context列,空值会自动返回null return country_df.get("context") display(df.withColumn("country_context", get_country_context(col("country"))))
方案2:先转JSON字符串再解析
如果你需要完整的字典结构做更复杂的处理,可以先把Struct列转成JSON字符串,再传入UDF解析:
from pyspark.sql.functions import pandas_udf, col, to_json import pandas as pd import json @pandas_udf("string") def get_country_context(country_str_series: pd.Series) -> pd.Series: def parse_context(s): if pd.isna(s): return None return json.loads(s).get("context") return country_str_series.apply(parse_context) display(df.withColumn("country_context", get_country_context(to_json(col("country")))))
内容的提问来源于stack exchange,提问作者Tytire Recubans
相关产品推荐
相关产品推荐

