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

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)

额外优化建议

  1. 批量请求提升效率:OSM API支持批量请求(比如https://api.openstreetmap.org/api/0.6/nodes?nodes=32321,32312,2133432),可以把每行的node列表拼接成批量请求URL,减少HTTP请求次数,大幅提升处理速度。
  2. 添加结果缓存:如果不同行有重复的node ID,可以缓存已经请求过的坐标,避免重复请求相同资源。
  3. 避免逐行IO操作:apply是逐行处理,IO操作本身较慢,建议先收集所有需要请求的node ID,批量请求后再将结果映射回DataFrame。

内容的提问来源于stack exchange,提问作者DRobins

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.29 21:27:33