最稳妥的 loc 条件赋值写法是 df.loc[condition, col] = value,其中 condition 为布尔序列、col 为单列名或列名列表,逗号分隔;多条件须用括号和 & 连接;修改多列可传列表或字典;避免链式赋值和 df[col][condition] 写法。

用 loc 按条件修改单列或少数列最稳妥
直接赋值给 df['col'][condition] 会触发 SettingWithCopyWarning,本质是链式赋值风险。必须用 loc 显式定位。
- 写法:
df.loc[df['A'] > 5, 'B'] = 'high'—— 条件在前,列名在后,中间用逗号分隔 - 支持多条件:
df.loc[(df['A'] > 5) & (df['C'] == 'x'), 'B'] = 'flag'(注意括号和&,不用and) - 可同时改多列:
df.loc[cond, ['B', 'D']] = ['val1', 'val2']或传入字典{'B': 'val1', 'D': 'val2'} - 如果目标列不存在,
loc不会自动创建,得先df['new_col'] = np.nan再赋值
用 numpy.where 批量生成新列效率更高
当逻辑是“if-else”二选一,且要生成新列或覆盖整列时,np.where 比 loc 更快,也更易读。
- 基础用法:
df['status'] = np.where(df['score'] >= 60, 'pass', 'fail') - 嵌套多层:
np.where(df['score'] >= 90, 'A', np.where(df['score'] >= 80, 'B', 'C')) - 注意:所有分支返回类型最好一致,否则 pandas 可能推断为
object,影响后续数值计算 - 不能用它修改原地某几行——它总是返回等长数组,适合全量生成
避免用 apply 做简单条件赋值
apply 看似灵活,但对纯条件判断属于杀鸡用牛刀,性能差、易出错。
- 错误示范:
df['label'] = df.apply(lambda r: 'big' if r['size'] > 10 else 'small', axis=1)—— 这比np.where慢 5–10 倍 - 仅当逻辑依赖多个列的复杂计算(比如调用外部函数、正则匹配、状态累积)才考虑
apply - 若真要用,务必加
axis=1,否则默认按列操作,结果完全不对 - 返回值必须明确,空
return会导致该行变成None
修改含 NaN 的列时,条件判断要小心
pandas 中 NaN == NaN 为 False,NaN > 5 是 False,但 NaN 本身不是布尔值,直接用于条件会报错或意外跳过。
- 安全写法:用
pd.isna()或df['col'].isna()单独判断缺失值 - 组合条件时别写
df['col'] > 5 or df['col'].isna()——or不支持向量化,改用|:(df['col'] > 5) | df['col'].isna() - 如果想把
NaN当作某个默认值参与比较,先用fillna(),比如df['col'].fillna(0) > 5 - 用
loc修改时,若条件里含isna(),目标列对应位置也会被设为新值,包括原本是NaN的行
None、空字符串、负零、时区感知时间等特殊值。动手前先用 df['col'].unique() 或 df['col'].describe(include='all') 快速扫一眼数据分布。Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!











