Pandas DataFrame含datetime64列执行update触发FutureWarning的疑问
Pandas更新含datetime64列的DataFrame触发FutureWarning的解决方案
问题描述
使用pd.DataFrame.update()方法用一个DataFrame更新另一个时,多数场景运行正常,但当目标DataFrame包含datetime64类型列时,会触发FutureWarning。
复现代码
import pandas as pd index = pd.to_datetime(['01/03/2022', '01/04/2022']) data1 ={'value': pd.to_datetime(['01/05/2022', '01/06/2022'])} data2 ={'value': pd.to_datetime(['01/05/2022', '01/07/2022'])} df1 = pd.DataFrame(data=data1, index=index) df2 = pd.DataFrame(data=data2, index=index) df1.update(df2)
触发的警告信息
FutureWarning: In a future version, `df.iloc[:, i] = newvals` will attempt to set the values inplace instead of always setting a new array. To retain the old behavior, use either `df[df.columns[i]] = newvals` or, if columns are non-unique, `df.isetitem(i, newvals)` df1.update(df2)
由于场景中列数不固定,警告提示的解决方案不适用,针对以下问题给出解答:
问题解答
1. 高效的推荐解决方法
推荐两种适配列数不固定场景的方案:
方案一:使用
where方法实现等价逻辑
完全替代update的功能(用df2的非空值覆盖df1对应位置),且不会触发警告:# 用df2的非空值替换df1对应元素,和update逻辑一致 df1 = df1.where(df2.isna(), df2)如果需要原地修改(不生成新DataFrame),可以用:
df1.where(df2.isna(), df2, inplace=True)方案二:针对性处理datetime列
仅对datetime64类型列单独用loc更新,其他列保留原update逻辑,兼顾效率和兼容性:for col in df1.columns: if pd.api.types.is_datetime64_dtype(df1[col]): # 筛选df2中当前列非空的行,批量更新df1 mask = df2[col].notna() df1.loc[mask, col] = df2.loc[mask, col] else: # 非datetime列继续用update df1.update(df2[[col]])
2. 能否忽略该警告
可以临时忽略,但不推荐长期忽略——这是Pandas的未来行为变更预警,未来版本可能修改iloc赋值逻辑,导致现有代码出现兼容性问题。
临时忽略的两种方式:
- 全局忽略指定警告:
import warnings warnings.filterwarnings( "ignore", category=FutureWarning, message=r"In a future version, `df.iloc\[:, i\] = newvals` will attempt to set the values inplace instead of always setting a new array." ) - 上下文管理器临时忽略(仅作用于指定代码块):
import warnings with warnings.catch_warnings(): warnings.simplefilter("ignore", FutureWarning) df1.update(df2)
3. 大量此类警告是否会导致性能问题
警告本身不会造成显著的性能损耗,仅会占用控制台IO资源。但如果在循环中频繁触发,可能会有轻微的输出延迟。
更关键的问题是:大量警告会掩盖其他重要的报错信息,且未来Pandas版本升级后,当前代码的逻辑可能因底层行为变更而失效,因此不建议依赖“忽略警告”的方式长期运行。
内容的提问来源于stack exchange,提问作者mike01010
相关产品推荐
相关产品推荐

