如何用Python从DataFrame的IP地址列生成对应城市列?
问题:根据IP地址为DataFrame新增城市列
我有一个名为loaddata1的DataFrame,其中包含IP_Adress列用于存储IP地址,想要新增一列city来显示每个IP对应的城市。IP_Adress列存在部分空值,我尝试了以下代码但无法正常运行:
loaddata1 = pd.DataFrame({'ip': loaddata1['IP_Adress']})
loaddata1['city'] = loaddata1.loc[loaddata1['ip'].notna(), 'ip'].apply(lambda x: geocoder.ip(x).city) print(loaddata1['IP_Adress'], loaddata1['city'])
运行后出现报错,无法得到预期结果。
解决方案
问题分析
- 第一行代码将原
loaddata1替换为仅含ip列的新DataFrame,导致原IP_Adress列丢失,后续打印时会因找不到该列报错。 - 直接使用
geocoder.ip(x).city未做异常处理,遇到无效IP、API请求失败时会直接中断程序。 - 空值处理逻辑不够严谨,容易引发不必要的调用。
修正后的代码
首先确保安装依赖库:
pip install pandas geocoder
然后执行以下代码:
import pandas as pd import geocoder # 定义IP转城市的函数,包含空值判断与异常捕获 def get_city(ip): if pd.isna(ip): return None try: geo_result = geocoder.ip(ip) # 如果解析不到城市,返回None return geo_result.city if geo_result.city else None except Exception as err: print(f"解析IP {ip}失败: {err}") return None # 直接在原DataFrame新增city列,保留原有数据结构 loaddata1['city'] = loaddata1['IP_Adress'].apply(get_city) # 查看结果 print(loaddata1[['IP_Adress', 'city']])
额外建议
如果遇到geocoder API请求频率限制或解析不稳定的情况,可以考虑使用本地IP数据库(如MaxMind的GeoIP2),无需依赖外部API,解析速度更快且更稳定。
内容的提问来源于stack exchange,提问作者Asif Sayed
相关产品推荐
相关产品推荐

