如何基于列值条件筛选特定Pandas分组?
基于列值条件筛选Pandas DataFrame指定分组的解决方案
问题描述
给定如下Pandas DataFrame:
import pandas as pd df = pd.DataFrame( { 'a': [10, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 65, 70, 10, 22], 'b': [1, 1, 1, -1, -1, -1, -1, 2, 2, 2, 2, -1, -1, -1, -1], 'c': [25, 25, 25, 45, 45, 45, 45, 65, 65, 65, 65, 40, 40, 30, 30] } )
需要按c列分组后,按照以下规则筛选结果:
- 筛选所有
b列值均为1的分组(本例仅c=25的组符合); - 筛选从DataFrame顶部开始的前2个
b列值均为-1的分组(本例符合条件的组有c=45、c=40、c=30,取前2个);
最终得到预期输出:
a b c 0 10 1 25 1 15 1 25 2 20 1 25 3 25 -1 45 4 30 -1 45 5 35 -1 45 6 40 -1 45 11 65 -1 40 12 70 -1 40
现有代码问题
你的尝试代码中,df1的逻辑是正确的(筛选b全为1的分组),但new_gb部分直接取了前2个分组,没有判断这些分组是否满足b全为-1的条件,因此无法得到正确结果。
修正后的解决方案
import pandas as pd df = pd.DataFrame( { 'a': [10, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 65, 70, 10, 22], 'b': [1, 1, 1, -1, -1, -1, -1, 2, 2, 2, 2, -1, -1, -1, -1], 'c': [25, 25, 25, 45, 45, 45, 45, 65, 65, 65, 65, 40, 40, 30, 30] } ) # 筛选所有b列全为1的分组 df_all_1 = df.groupby('c').filter(lambda g: g['b'].eq(1).all()) # 获取原DataFrame中c列的唯一值顺序(保持出现先后) unique_c_order = df['c'].unique() # 筛选出b列全为-1的c值,并按原顺序取前2个 valid_neg1_c = [] for c in unique_c_order: group = df[df['c'] == c] if group['b'].eq(-1).all(): valid_neg1_c.append(c) if len(valid_neg1_c) == 2: break # 取到前2个就停止 # 获取前2个b全为-1的分组数据 df_top2_neg1 = df[df['c'].isin(valid_neg1_c)] # 合并两个结果,保持原DataFrame中的行顺序 result = pd.concat([df_all_1, df_top2_neg1]).sort_index() print(result)
代码说明
- 筛选全1分组:使用
groupby.filter直接过滤出b列所有值都是1的分组; - 保持分组出现顺序:通过
df['c'].unique()获取原DataFrame中c值的出现顺序,避免groupby默认的排序打乱顺序; - 筛选前2个全-1分组:遍历唯一
c值,检查每个分组是否满足b全为-1,收集到2个符合条件的c值后停止; - 合并结果:将两部分数据合并后按原索引排序,保证输出顺序和原DataFrame一致。
内容的提问来源于stack exchange,提问作者AmirX
相关产品推荐
相关产品推荐

