pandas遍历含字符串与NaN的列时如何正确判断非NaN值避免报错
逐行判断pandas列字符串/NaN混合值的正确方法
问题背景
DataFrame中存在names列,列内混合两类值:
- 有效条目:
name1、name2这类字符串(str类型) - 缺失条目:
NaN(float类型)
列样例如下:
names name1 NaN name2 NaN
初始实现用for循环逐行处理,调用isnull()、math.isna()做判断时报错:
- 对单元格值直接调用
.isnull()触发AttributeError: 'str' object has no attribute 'isnull' - 改用lambda函数匹配时触发
TypeError: expected string or bytes-like object
需求为遍历列时仅修改有效字符串条目,完整保留NaN条目不做处理。
报错原因
.isnull()是pandas Series、DataFrame对象的内置方法,不是Python原生字符串、浮点数对象的方法,直接对取出来的单个单元格字符串值调用,必然会触发属性不存在的报错。
可行实现
优先推荐:向量化操作(性能远高于逐行for循环)
如果不需要逐行写复杂分支逻辑,直接用pandas原生的Series级判断筛出有效行处理即可,NaN行会自动保留原值:
# 生成非空值的筛选掩码 valid_mask = df["names"].notna() # 仅对非空的字符串条目做自定义处理 df.loc[valid_mask, "names"] = df.loc[valid_mask, "names"].apply( lambda s: # 此处写入字符串处理逻辑,比如s.upper()、正则替换等 )
必须逐行for循环的判断写法
如果业务逻辑必须逐行遍历分支处理,可选用以下两种稳定判断方式,不会触发类型报错:
- 用pandas通用缺失值判断函数
pd.isna()
该函数可以兼容判断所有类型的对象,包括字符串、浮点数、None等,是通用性最高的写法:
import pandas as pd for idx in range(len(df)): cell_val = df.loc[idx, "names"] if not pd.isna(cell_val): # 此处写入字符串处理逻辑,处理完赋值回对应位置 df.loc[idx, "names"] = processed_result
- 基于类型判断(适配当前列固定类型分布)
当前列有效值全为str类型、NaN全为float类型,直接判断值类型即可,判断性能更高:
for idx in range(len(df)): cell_val = df.loc[idx, "names"] if isinstance(cell_val, str): # 确认是有效字符串,执行处理后赋值 df.loc[idx, "names"] = processed_result
避坑说明
- 禁止用
val == float('nan')或val == np.nan做判断:NaN的特性是和任何值(包括自身)做相等比较都返回False,该判断永远不成立 - 逐行赋值时优先用
df.loc[idx, col_name]的写法,避免链式索引触发SettingWithCopyWarning警告,导致赋值不生效 math.isnan()仅能判断数值类型的NaN,传入字符串时会直接抛类型错误,不适合混合类型列的判断
内容的提问来源于stack exchange,提问作者KLG
相关产品推荐
相关产品推荐

