使用pandas_udf调用Nominatim API报错:结果向量长度不符
问题原因
标量类型的pandas_udf接收的参数是Pandas Series对象,而非单个数值。你的代码直接将整个Series拼接到URL中,导致API请求参数异常,同时返回的是单个字符串(而非与输入Series长度匹配的Series),触发了长度不匹配的错误。
修复方案
需要遍历输入的经纬度对,逐个调用API,并将结果整理为Pandas Series返回。另外,Nominatim API有访问频率限制,建议添加请求延迟避免被封禁。
修复后的代码:
import requests import pandas as pd import time from pyspark.sql.functions import pandas_udf, PandasUDFType @pandas_udf("string", PandasUDFType.SCALAR) def country_name(lat_series, lon_series): results = [] for lat, lon in zip(lat_series, lon_series): # 遵守API访问规则,添加1秒间隔 time.sleep(1) url = f"https://nominatim.openstreetmap.org/reverse?format=json&lat={lat}&lon={lon}" try: response = requests.get(url) response.raise_for_status() data = response.json() if 'error' in data: results.append('NA') else: results.append(data['address'].get('country', 'NA')) except Exception: # 捕获网络或解析错误,返回默认值 results.append('NA') # 返回与输入长度匹配的Pandas Series return pd.Series(results) df = spark.createDataFrame([(40.730610, -73.935242), (35.6762, 139.6503)], ["lat", "lon"]) df = df.withColumn("country", country_name(df["lat"], df["lon"])) df.show()
关键说明
- 遍历
lat_series和lon_series的每一对元素,逐个处理API请求 - 返回值必须是Pandas Series,保证与输入的长度严格一致
- 添加
time.sleep(1):Nominatim API要求单次请求间隔至少1秒,否则可能被临时封禁 - 增加异常捕获:处理网络故障、API返回异常等情况,避免UDF崩溃
内容的提问来源于stack exchange,提问作者BryC
相关产品推荐
相关产品推荐

