如何按category分组筛选出所有值均为'no'的site列?
解决方案
先把你的数据转换成DataFrame:
import pandas as pd data = {'category':['foo','foo','foo','foo','foo','bar','bar','bar','bar','bar'],'part':['101','102','103','104','105','201','202','203','204','205'],'site_a':['yes','yes','no','no','no','no','yes','no','no','no'],'site_b':['no','no','no','no','no','no','yes','no','no','no'],'site_c':['yes','no','no','no','no','no','no','no','no','no']} df = pd.DataFrame(data)
方法1:直接用groupby结合all()判断
我们可以按category分组后,对每个分组的site列(site_a、site_b、site_c)检查是否所有值都是'no':
# 定义函数,返回分组中全为'no'的列名列表 def get_all_no_cols(group): return group.columns[group.eq('no').all()].tolist() # 按category分组应用函数,得到每个分组对应的目标列 result = df.groupby('category').apply(get_all_no_cols)
运行后result的输出为:
category foo [site_b] bar [site_c] dtype: object
方法2:转换为数值后判断总和
如果你倾向于把'yes'转1、'no'转0的思路,可以这样实现:
# 把site列的yes/no转成0/1(yes=1,no=0) site_cols = ['site_a', 'site_b', 'site_c'] df[site_cols] = df[site_cols].replace({'yes':1, 'no':0}) # 按category分组求和,总和为0的列就是全为'no'的列 sum_result = df.groupby('category')[site_cols].sum() # 筛选出总和为0的列,整理成结果 result = sum_result.apply(lambda x: x[x == 0].index.tolist(), axis=1)
这个方法和方法1的结果完全一致。
针对多索引的情况
如果你已经设置了['category','part']为多索引,直接用索引层级分组即可:
# 先设置多索引 df.set_index(['category','part'], inplace=True) # 按category索引分组,应用方法1的函数 result = df.groupby(level='category').apply(get_all_no_cols)
同样能得到正确结果。
补充说明
group.eq('no').all():eq('no')会把列中每个值和'no'比较生成布尔值DataFrame;all()会检查列内所有值是否为True(即全为'no')。- 两种方法都能高效满足需求,方法1更直观,方法2适合需要后续数值计算的场景。
内容的提问来源于stack exchange,提问作者Brad
相关产品推荐
相关产品推荐

