DataFrame中apply函数无法正确遍历列表元素的问题排查
问题排查与修复
你的代码里有两个关键问题导致每次只处理列表的第一个元素,还会出现结果混乱的情况:
1. return 语句位置错误
在FindNodeLL函数中,你把return RouteNodeLL放在了for node in route_nodes:的循环内部,这意味着第一次处理完一个node之后,函数就直接返回结果了,后面的node根本没有机会进入循环执行。
2. 使用全局列表导致结果累积
RouteNodeLL看起来是一个全局定义的列表,每次调用函数时不会自动清空,新处理的结果会追加到旧列表里,导致后续行的结果包含前面所有行的处理数据,而不是当前行独立的结果。
修复后的代码
import requests import xml.etree.ElementTree as ET def FindNodeLL(route_nodes): # 每次调用函数时创建新的空列表,存储当前行的专属结果 route_node_ll = [] for node in route_nodes: try: # 添加超时设置,避免请求长时间卡住 response_xml = requests.get(f'https://api.openstreetmap.org/api/0.6/node/{node}', timeout=10) # 主动检查请求是否成功,防止解析错误响应 response_xml.raise_for_status() responseXml = ET.fromstring(response_xml.content) for child in responseXml.iter('node'): route_node_ll.append((float(child.attrib['lat']), float(child.attrib['lon']))) except requests.exceptions.RequestException as e: # 捕获请求相关异常,方便排查具体问题 print(f"请求node {node}时出错: {e}") except ET.ParseError as e: # 捕获XML解析异常 print(f"解析node {node}的响应时出错: {e}") # 尽量避免裸except,否则会掩盖未知错误 # 等所有node处理完成后,再返回当前行的完整结果 return route_node_ll # 注意:原代码里你写的是row['Route Nodes'],但你的DataFrame列名是Nodes,这里要对应上! df['Route Nodes LL'] = df.apply(lambda row: FindNodeLL(row['Nodes']), axis=1)
额外优化建议
- 批量请求提升效率:OSM API支持批量请求(比如
https://api.openstreetmap.org/api/0.6/nodes?nodes=32321,32312,2133432),可以把每行的node列表拼接成批量请求URL,减少HTTP请求次数,大幅提升处理速度。 - 添加结果缓存:如果不同行有重复的node ID,可以缓存已经请求过的坐标,避免重复请求相同资源。
- 避免逐行IO操作:apply是逐行处理,IO操作本身较慢,建议先收集所有需要请求的node ID,批量请求后再将结果映射回DataFrame。
内容的提问来源于stack exchange,提问作者DRobins
相关产品推荐
相关产品推荐

