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

Python与Pandas新手:调用邮编API获取经纬度并写入DataFrame时遭遇NotImplementedError问题求助

解决Pandas处理邮编API时的NotImplementedError问题

首先,咱们来拆解你遇到的问题:

错误原因分析

你看到的NotImplementedError是因为**pd.json_normalize()用错了场景**。这个函数是用来把嵌套的JSON结构(比如包含字典的列表)转换成DataFrame的,但parse_json['data']['latitude']是一个单个的数值(字符串或数字类型),不是可迭代的JSON结构,所以用json_normalize处理单个值就会触发这个错误。

另外,你的代码还有一个隐藏问题:在for循环里直接给df_cust["Lat"]和df_cust["Long"]赋值,会导致每次循环都覆盖整列的数据,最后所有行的坐标都会变成最后一个邮编的结果,而不是对应各自的邮编。

修复后的代码方案

下面是修正后的代码,同时加入了异常处理(避免API请求失败导致程序崩溃),并且保证每个邮编对应自己的坐标:

import pandas as pd
import requests
import json

# 假设你的con_str已经正确定义
query_cust = "select custMasterID,Full_Name,POSTCODE from DMON.BANK_CUSTOMERS"
df_cust = pd.read_sql(query_cust, con=con_str)
df_cust["URL"] = "https://api.getthedata.com/postcode/" + df_cust['POSTCODE'].str.replace(" ", "")

# 先初始化Lat和Long列,避免KeyError
df_cust["Lat"] = None
df_cust["Long"] = None

# 遍历每一行,用索引定位赋值
for idx, row in df_cust.iterrows():
    url = row["URL"]
    try:
        response = requests.get(url)
        response.raise_for_status()  # 检查请求是否成功(比如404、500错误)
        parse_json = response.json()  # 直接用response.json()代替json.loads(response.text)更简洁
        
        # 直接赋值单个数值,不需要json_normalize
        df_cust.loc[idx, "Lat"] = parse_json['data']['latitude']
        df_cust.loc[idx, "Long"] = parse_json['data']['longitude']
    except Exception as e:
        print(f"处理邮编{row['POSTCODE']}时出错: {str(e)}")
        # 出错时可以选择保留None,或者赋值默认值
        df_cust.loc[idx, "Lat"] = None
        df_cust.loc[idx, "Long"] = None

print(df_cust)

关键优化点说明

  1. 替换json_normalize为直接赋值:因为latitude和longitude都是单个值,直接提取后赋值给对应行的列即可。
  2. 用iterrows()遍历行+loc定位:这样能保证每个邮编的坐标对应到自己的行,不会覆盖整列。
  3. 异常处理:加入try-except块和response.raise_for_status(),处理API请求失败的情况(比如无效邮编、网络波动),让程序更健壮。
  4. 简化JSON解析:用response.json()代替json.loads(response.text),这是requests库提供的更简洁的JSON解析方法。

更高效的Pandas风格写法(可选)

如果你的数据量较大,iterrows()的效率可能不高,可以用apply方法来替代循环:

def get_coords(row):
    url = row["URL"]
    try:
        response = requests.get(url)
        response.raise_for_status()
        data = response.json()['data']
        return pd.Series([data['latitude'], data['longitude']])
    except Exception as e:
        print(f"处理邮编{row['POSTCODE']}时出错: {str(e)}")
        return pd.Series([None, None])

# 同时生成Lat和Long列
df_cust[["Lat", "Long"]] = df_cust.apply(get_coords, axis=1)

这种写法更符合Pandas的向量化操作思路,代码也更简洁。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.30 19:27:27