numpy.where 更稳、可嵌套、向量化快,避免 df.loc 堆叠布尔条件出错;assign 链式处理多步逻辑更安全;map 适合跨列查表映射;禁用逐行 loc 赋值,优先向量化。

用 numpy.where 处理多条件跨列赋值
直接在 df.loc 里堆叠多个布尔条件容易出错,尤其当涉及 NaN 或类型不一致时,numpy.where 更稳。它支持嵌套、可读性强,且向量化快。
常见错误是写成 df['C'] = (df['A'] > 0) & (df['B'] == 'x') ? 1 : 0 —— Python 没有三元操作符这么用,会报 SyntaxError 或返回全 False 数组。
- 基础用法:
df['C'] = np.where((df['A'] > 0) & (df['B'].str.contains('x', na=False)), 1, 0) - 嵌套三层逻辑:
df['status'] = np.where(df['score'] >= 90, 'A', np.where(df['score'] >= 60, 'B', 'C')) -
na=False必须显式加在str.contains()里,否则遇到NaN直接抛ValueError
用 df.assign() + lambda 链式处理复杂逻辑
当逻辑需要多步中间变量(比如先算比率、再分档、再映射标签),assign 比反复赋值更安全,避免污染原始 DataFrame,也方便调试。
注意:lambda x: ... 中的 x 是整张 DataFrame,不是单列;若只依赖某几列,务必用 x[['A','B']] 显式切片,否则可能因列顺序变动或新增列导致逻辑错乱。
- 示例:
df = df.assign(ratio=lambda x: x['A'] / x['B'].replace(0, np.nan), level=lambda x: pd.cut(x['ratio'], bins=[0,1,2,5], labels=['low','mid','high'])) -
replace(0, np.nan)比np.divide(x['A'], x['B'], out=np.zeros_like(...), where=x['B']!=0)更直观,且自动传播NaN - 别在
assign里调用会修改原df的函数(如.fillna(inplace=True)),会导致未定义行为
用 pd.Series.map() + 自定义函数处理非标映射逻辑
当跨列组合后需查表或执行含副作用的逻辑(比如根据 A/B 值查配置字典、调外部 API),map 搭配元组索引比 apply 更高效,且能缓存结果。
容易踩的坑是忘记把多列合成 tuple:直接 df[['A','B']].map(...) 会报 AttributeError,因为 map 不支持 DataFrame。
- 正确做法:
df['label'] = df.apply(lambda r: (r['A'], r['B']), axis=1).map(mapping_dict).fillna('unknown') - 更高效写法:
df['key'] = list(zip(df['A'], df['B'])),再df['label'] = df['key'].map(mapping_dict) - mapping_dict 键必须是不可变类型;若 A/B 含
NaN,zip会变成(nan, value),而np.nan != np.nan,查不到键——得提前用df['A'].fillna(-999)统一占位
性能陷阱:避免在循环中用 df.loc[i, 'col'] = ...
逐行赋值看着直观,但哪怕只有几千行,速度也会比向量化慢 10–100 倍,且容易因索引对齐问题写到错行(尤其用了 reset_index(drop=True) 后又按原位置赋值)。
真正没法向量化的场景极少,多数时候只是没找到合适的 groupby().transform()、shift() 或 rolling() 组合。先确认是否真不能向量化,再考虑 itertuples()。
- 安全替代:
for idx, row in df.iterrows():→ 改用for row in df.itertuples():,row.Index和row.A访问更快,且不触发隐式拷贝 - 如果必须改原
df某行某列,用df.loc[row.Index, 'C'] = new_value,别用df.iloc[i, j]—— 行序可能已变 - 测试时用
df.head(3).copy()跑逻辑,别直接在全量数据上试错
where、assign 还是 map,比直接敲代码更省时间。Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!











