如何在 Pandas 中删除所有不包含指定值(如 ‘PC’)的行

10次阅读

如何在 Pandas 中删除所有不包含指定值(如 ‘PC’)的行

本文介绍如何使用布尔索引高效筛选 dataframe:保留至少在一列中含 ‘pc’ 的行,或反向删除全都不含 ‘pc’ 的行,重点解决跨多列(如列 0–11)的条件行过滤问题。

在实际数据清洗中,常需基于多列中是否存在某个特定值(如 ‘PC’)来保留或剔除整行。你提供的数据包含编号为 0 到 11 的 12 列(类型为 Object),其中部分单元格值为 ‘PC’,其余可能为 ‘False’ 或其他字符串。你的目标是:仅保留那些在列 0–11 中至少出现一次 ‘PC’ 的行——换句话说,删除所有在这 12 列中完全不包含 ‘PC’ 的行

⚠️ 注意:你尝试的几种方法存在典型误区:

  • 使用 iterrows() + drop() 在循环中修改 DataFrame 是低效且危险的(可能导致索引错乱或 SettingWithCopyWarning);
  • df[df[‘column’] == ‘PC’] 只能作用于单列,无法跨列逻辑;
  • df[colum_pc].apply(…, axis=1) 中 row.values 在 Series 上调用会返回 numpy.ndarray,但 in 检查对数组行为不可靠(应改用 .isin([‘PC’]).any());拼写错误 colum_pc 也会报错。

✅ 正确、高效、向量化的方法是使用 布尔索引 + ne() + all()

# ✅ 保留「在前12列中至少有一个'PC'」的行(即:删除全都不含'PC'的行) mask = df.iloc[:, :12].ne('PC').all(axis=1)  # → True 表示该行在所有12列中都 ≠ 'PC' df_filtered = df[~mask].reset_index(drop=True)

等价地,更直观的写法(推荐初学者理解):

# ✅ 更清晰的逻辑:检查每行在0-11列中是否有至少一个'PC' has_pc = df.iloc[:, :12].eq('PC').any(axis=1)  # any() → True if at least one 'PC' exists df_filtered = df[has_pc].reset_index(drop=True)

? 原理解析:

  • df.iloc[:, :12]:按位置选取全部行、前 12 列(即列 0 至 11);
  • .eq(‘PC’):生成布尔 DataFrame,值为 True 当且仅当对应单元格等于 ‘PC’;
  • .any(axis=1):对每行判断——只要该行任一列为 True,结果即为 True;
  • 最终布尔序列用于索引,df[has_pc] 即完成精准行过滤。

? 补充说明:

  • 若列名非数字(如 ‘col_0’, ‘platform_1’),请改用列名列表:df[[‘col_0′,’col_1’,…, ‘col_11’]].eq(‘PC’).any(axis=1);
  • 若 ‘PC’ 可能混有空格或大小写(如 ‘pc’, ‘ Pc ‘),建议先标准化:df.iloc[:, :12].apply(Lambda x: x.str.strip().str.upper()).eq(‘PC’);
  • 对于超大表(如你数据的 51 万行),此向量化操作比 iterrows 快数十倍,且内存友好。

执行后,df_filtered 即为你所需的、已剔除“全无 ‘PC’”行的精简数据集,并自动重置了连续整数索引。

text=ZqhQzanResources