使用Pandas提取列中坐标时正则表达式失效返回NaN问题求助
解决Pandas正则提取坐标返回NaN的问题
嘿,我之前也碰到过一模一样的糟心事——正则在在线工具里明明能匹配,到了Pandas里却全返回NaN,真的挺挠头的!咱们一步步排查可能的原因,总能搞定:
1. 先确认原始字符串的真实模样
有时候我们肉眼看到的字符串和实际存储的不一样,比如藏着全角数字、不可见空格(比如非-breaking空格),或者坐标被引号、括号包裹但我们没留意。你可以先打印单个字符串的原始格式,看看有没有特殊字符:
# 取第一行数据查看真实内容 print(repr(data['geocode_result'].iloc[0]))
比如如果坐标是放在括号里的"上海 (31.2304, 121.4737)",那正则就得调整成匹配括号内的内容:
p = r'\((?P<latitude>-?\d+\.\d+),\s*(?P<longitude>-?\d+\.\d+)\)'
2. 正则是否兼容所有坐标格式?
你的正则-?\d+\.\d+只能匹配带小数的坐标,但如果有整数形式的坐标(比如-123而不是-123.45),就会直接匹配失败。可以修改正则兼容整数和小数:
p = r'(?P<latitude>-?\d+(?:\.\d+)?).*?(?P<longitude>-?\d+(?:\.\d+)?)'
这里(?:\.\d+)?表示小数部分是可选的,还不会额外创建捕获组。
3. 开启DOTALL模式处理换行符
Pandas的str.extract默认情况下,正则里的.不会匹配换行符。如果你的geocode_result列里有换行(比如坐标单独在新一行),那.*?就跨不过换行,导致匹配失败。可以开启DOTALL模式:
import re p = r'(?P<latitude>-?\d+\.\d+).*?(?P<longitude>-?\d+\.\d+)' data[['latitude', 'longitude']] = data['geocode_result'].str.extract(p, flags=re.DOTALL, expand=True)
或者直接在正则开头加(?s)(DOTALL的简写):
p = r'(?s)(?P<latitude>-?\d+\.\d+).*?(?P<longitude>-?\d+\.\d+)'
4. 检查列的类型和空值
如果geocode_result列不是纯字符串类型(比如object列混了非字符串值),或者有大量空值,也会导致提取失败。先做个简单检查:
# 查看列类型 print(data['geocode_result'].dtype) # 统计空值数量 print(data['geocode_result'].isna().sum()) # 统一转成字符串类型 data['geocode_result'] = data['geocode_result'].astype(str)
快速测试正则匹配
你可以单独拿一个字符串测试正则,确认是不是正则本身的问题:
test_str = data['geocode_result'].iloc[0] match = re.search(p, test_str) if match: print("匹配成功!", match.groupdict()) else: print("匹配失败,得再调整字符串或正则!")
按这个流程排查,大概率能找到问题所在~
内容的提问来源于stack exchange,提问作者SuperSecretAndNotSafeFromWork
相关产品推荐
相关产品推荐

