如何无警告筛选DataFrame修改列值并仅追加筛选子集?
DataFrame筛选修改后追加的无警告实现
问题背景
需要筛选DataFrame的指定子集,修改部分列值后将该子集追加回原DataFrame。原代码可实现功能但持续触发SettingWithCopyWarning,改用.loc后错误地全量追加了修改后的完整副本,而非仅目标筛选子集。
原代码(触发警告)
end_previous_month = EndDate.replace(day=1) - timedelta(days=1) end_previous_month = end_previous_month.strftime("%Y/%m/%d") df1 = df[(df['Account.DisplayID'] == "1-1110") & (df['CompanyKey'] != 4) & (df['DateOccurred'] <= end_previous_month)] df1['Account.Name'] = 'Opening Balance' df1['Account.DisplayID'] = '10-0001' df1['DisplayID'] = "" df = pd.concat([df, df1])
错误尝试代码(全量追加)
end_previous_month = EndDate.replace(day=1) - timedelta(days=1) end_previous_month = end_previous_month.strftime("%Y/%m/%d") df1 = df.copy() m = (df['Account.DisplayID'] == "1-1110") & (df['CompanyKey'] != 4) & (df['DateOccurred'] <= end_previous_month) df1.loc[m, ['Account.Name', 'Account.DisplayID', 'DisplayID']] = ['Opening Balance', '10-0001', ""] df = pd.concat([df, df1])
正确解决方案
核心是先筛选目标子集并创建独立副本,再修改副本列值,最后仅追加该子集:
import pandas as pd from datetime import timedelta end_previous_month = EndDate.replace(day=1) - timedelta(days=1) end_previous_month = end_previous_month.strftime("%Y/%m/%d") # 筛选子集并创建独立副本,彻底切断与原DataFrame的视图关联 df1 = df[(df['Account.DisplayID'] == "1-1110") & (df['CompanyKey'] != 4) & (df['DateOccurred'] <= end_previous_month)].copy() # 修改副本的列值,此时用.loc或直接赋值都不会触发警告 df1.loc[:, ['Account.Name', 'Account.DisplayID', 'DisplayID']] = ['Opening Balance', '10-0001', ""] # 将修改后的子集追加到原DataFrame,建议加ignore_index=True避免索引冲突 df = pd.concat([df, df1], ignore_index=True)
关键说明
- 原代码警告原因:
df[条件]返回的是原DataFrame的视图而非独立副本,直接修改视图会触发警告,存在修改原数据的风险。 - 错误尝试问题:复制了整个DataFrame,修改后全量追加,不符合仅追加筛选子集的需求。
- 正确逻辑:
.copy()创建独立副本后,副本与原DataFrame完全独立,修改操作不会影响原数据,也不会触发警告,最终仅追加目标子集。
内容的提问来源于stack exchange,提问作者Jered
相关产品推荐
相关产品推荐

