Pandas:如何从YES/NO型未知规模DataFrame中提取所有值为YES的行索引与列名配对
全表匹配YES单元格的行列配对实现
针对从电子表格读入、预先不知道行列规模的YES/NO值DataFrame,不需要逐列写筛选逻辑,用Pandas内置的长表转换能力即可实现全表批量匹配,方案完全适配未知表格规模的场景。
核心实现步骤(零手动枚举列名)
1. 最简推荐方案(新手易理解、无冗余代码)
利用stack()方法自动将宽表转换为长表结构,自动记录每一个单元格对应的行索引、列名,全程不需要手动指定列名、行数,适配电子表格读取的未知结构:
# 预处理(*新手常见坑*:从Excel读入的单元格经常带前后空格,导致匹配失效) df = df.apply(lambda x: x.str.strip()) # 长表转换:自动生成 行索引、列名、单元格取值 三列 long_df = df.stack().reset_index() # 对列做易读性命名 long_df.columns = ['行索引', '列名', '单元格值'] # 筛选值为YES的配对结果 result = long_df.loc[long_df['单元格值'] == 'YES', ['列名', '行索引']]
运行后result的输出完全匹配预期格式:
| 列名 | 行索引 |
|---|---|
| David | task1 |
| David | task4 |
| Carol | task1 |
| Carol | task2 |
| Anna | task4 |
2. 链式简化写法(代码更紧凑)
利用新版本Pandas的参数,把步骤合并成链式调用,减少中间变量的定义:
result = ( df.stack() # 直接给转换后的三列命名,无需手动改列名 .reset_index(names=['行索引', '列名', '单元格值']) # 直接筛选值为YES的行 .query("单元格值 == 'YES'") # 保留需要的两列 [['列名', '行索引']] )
其他输出格式适配
如果不需要DataFrame格式的结果,可以在上面的result基础上直接转换,无需重新计算:
- 转成二维数组:使用代码
result.values - 转成配对元组列表:使用代码
list(result.itertuples(index=False, name=None))
方案优势说明
你之前尝试的单列loc筛选逻辑,需要手动指定每一列的列名做判断,一旦从电子表格读入的列数未知(比如今天读的表是5列,明天是20列),就需要反复修改代码写筛选条件。而上述的stack()转换逻辑,会自动遍历全表所有单元格,不管表有多少行、多少列,代码都不需要做任何修改,完全满足灵活适配不同规模电子表格的需求。
内容的提问来源于stack exchange,提问作者nico
相关产品推荐
相关产品推荐

