修改Pandas.DataFrame切片副本触发警告,用numpy.where无警告的原因是什么
两种写法触发警告差异的原因
1. 链式索引触发SettingWithCopyWarning的原理
你触发警告的写法df['trade_status'][df['trade_status'] == 'DONE'] = 'FILLED'属于典型的链式索引操作:
- 执行顺序是先运行
df['trade_status']从DataFrame中提取列对象,Pandas此时无法明确返回的是原DataFrame的视图还是独立生成的副本 - 第二步对第一步返回的对象再做布尔索引赋值,Pandas的安全检测机制判定你正在给一个来源属性不明确的切片对象赋值,有可能出现「你想修改原DataFrame但实际只修改了临时副本、修改不生效」的问题,因此抛出警告。
注意:即使你前面执行了
df = input_df.copy()生成了独立的df对象,警告依然会触发——因为这个检测是针对赋值操作的链式结构本身,不校验df的来源。
2. numpy.where写法无警告的原因
df['trade_status'] = np.where(df['trade_status'] == 'DONE', 'FILLED', df['trade_status'])不属于链式索引,是直接对原DataFrame列做整体赋值:
np.where会先根据条件计算得到一个和trade_status列长度完全一致的新数组- 之后直接把整个新数组一次性赋值给
df['trade_status'],整个操作只有一次对df的直接赋值,没有对中间切片对象赋值的步骤,因此不会触发切片副本的安全检测。
推荐的替代写法
Pandas官方更推荐用.loc实现条件赋值,既不会触发警告,可读性也更高:
df.loc[df['trade_status'] == 'DONE', 'trade_status'] = 'FILLED'
内容的提问来源于stack exchange,提问作者Coding Baby
相关产品推荐
相关产品推荐

