Pandas使用df.loc筛选后已删除行仍存在的技术求助
解决Pandas筛选后变量窗口仍显示已删除行的坑
兄弟,这问题我踩过好多次!核心就是你看到的那个SettingWithCopyWarning——你手里的df根本不是独立的DataFrame,而是另一个数据的视图(view),不是副本(copy),这就导致操作出现“表面生效但底层没彻底切断关联”的诡异情况。
为啥会这样?
你看你操作的步骤:
- 用
fillna(inplace=True)原地填充Tobacco列的空值 - 筛选出符合条件的行重新赋值给
df
但如果df是从原数据(比如你导入后做过切片,比如df = raw_df[['A', 'Tobacco', 'B']])来的视图,那inplace=True的操作其实是在修改视图背后的原数据,后续的筛选赋值并没有真正生成全新的DataFrame。结果就是:len(df)显示正确的7000行,但变量查看器(不管Spyder还是PyCharm)还能看到原数据的索引范围(到8000),不过这些“幽灵行”其实不参与后续计算——你说循环处理不受影响,就是因为Pandas内部还是认筛选后的7000行,只是索引没清理干净,查看器懵了。
怎么解决?
1. 先给df“独立身份”:生成副本
不管是导入CSV后,还是从原数据切片得到df,直接加.copy()生成独立副本,从根源切断和原数据的关联:
import pandas as pd # 导入CSV时直接生成副本 df = pd.read_csv("你的数据文件.csv").copy() # 要是从原数据切片来的df,也必须加.copy() # df = raw_df[['需要的列1', 'Tobacco', '需要的列2']].copy()
2. 优化操作逻辑,别用inplace
把填充空值和筛选合并成一步,不用inplace=True,减少踩坑概率:
# 合并填充与筛选,直接得到新的df df = df[df['Tobacco'].fillna('No involvement') == 'No involvement'] # 或者用更直观的query写法,自动处理空值 df = df.query("Tobacco == 'No involvement' or Tobacco.isna()")
3. 重置索引,清理“幽灵索引”
筛选完之后,重置索引让索引和实际行数完全对应,这样变量查看器就不会乱显示了:
df = df.reset_index(drop=True)
验证一下
按上面的步骤做完,再看len(df)肯定还是7000,打开变量窗口一看——索引从0到6999,之前那1000行彻底没了,完美解决!
内容的提问来源于stack exchange,提问作者Nhi Vo
相关产品推荐
相关产品推荐

