Pandas筛选指定前缀列匹配值返回全NaN 如何高效实现多列筛选
问题原因
你最初写的df[df.filter(like='Inc') == 'Yes']无法得到正确结果,核心原因是df.filter(like='Inc') == 'Yes'返回的是一个仅包含9个Inc列的布尔型DataFrame,用这个布尔DataFrame直接索引原表时,Pandas只会保留布尔值为True位置的单元格值,不在布尔判断范围内的非Inc列会被全部填充为NaN,因此返回结果不符合预期。
高扩展性实现方案
不需要逐列手写与逻辑,用行方向的全值判断即可实现需求,后续Inc列数量增减时不需要修改代码:
- 基础写法(和你用
like='Inc'筛选列的逻辑完全对齐)
# 提取所有列名包含Inc的列,逐行判断是否所有取值均为Yes mask = df.filter(like='Inc').eq('Yes').all(axis=1) df_result = df[mask]
代码说明:
eq('Yes')等价于== 'Yes',是Pandas中推荐的元素级判断写法all(axis=1)会按行检查判断结果,只有该行所有Inc列的取值都是Yes时,对应行的mask值才为True最终返回的
df_result是原DataFrame中符合条件的所有行、所有列,和你逐列写与逻辑的运行结果完全一致。更严谨的写法(严格匹配「列名以Inc开头」的需求)
如果担心like='Inc'会误匹配到列名中间带Inc的列(比如列名A_Inc_test),可以用列名前缀匹配的方式筛选目标列,准确性更高:
# 先筛选所有以Inc为开头的列名 inc_cols = df.columns[df.columns.str.startswith('Inc')] mask = df[inc_cols].eq('Yes').all(axis=1) df_result = df[mask]
- 灵活扩展
如果后续需要调整筛选规则,比如只要8个及以上Inc列取值为Yes就保留行,只需要把判断逻辑稍作修改即可,不需要逐列调整:
# 满足Inc列取值为Yes的数量>=8即保留 mask = df.filter(like='Inc').eq('Yes').sum(axis=1) >= 8 df_result = df[mask]
内容的提问来源于stack exchange,提问作者Mohamed Gamal
相关产品推荐
相关产品推荐

