Python如何筛选DataFrame中某列含NaN值的所有行
解决方法
你的核心问题是错误地用类型判断来筛选NaN值——因为latitude列本身就是float类型,NaN也属于float,所以isinstance(row, float)会把所有行都标记为True,完全起不到筛选作用。
直接用pandas内置的isna()(或isnull(),两者功能一致)来生成布尔掩码,这是pandas中检测NaN最高效、最标准的方式:
修改后的完整代码
def boolean_mask_loop(df): # 直接生成针对latitude列NaN值的布尔掩码 msk = df['latitude'].isna() out = [] # 直接遍历筛选后的address列,无需转成list for target in df.loc[msk, 'address']: dict_temp = geocoding(target) out.append([dict_temp['lat'], dict_temp['long']]) # 批量更新对应行的latitude和longitude df.loc[msk, ['latitude', 'longitude']] = out return df
关键说明
- 掩码生成:
df['latitude'].isna()会返回一个和DataFrame行数一致的布尔Series,其中只有latitude为NaN的位置是True,完美匹配你的需求。 - 效率优化:避免了把列转成list再遍历的额外开销,pandas的矢量化掩码操作比手动列表推导快得多,尤其适合20000行的大数据量。
- 逻辑验证:针对你给出的示例DataFrame,这个掩码会精准选中id=1和id=2的行,调用
geocoding后更新对应的经纬度,不会影响id=3的有效数据。
额外优化建议(可选)
如果需要处理的NaN行数较多,循环调用geocoding会比较慢,可以考虑:
- 批量传递地址列表给地理编码接口(如果接口支持)
- 使用异步请求库(如
aiohttp)并发调用接口,减少等待时间
内容的提问来源于stack exchange,提问作者CGarden
相关产品推荐
相关产品推荐

