如何按PP分组的四分位数筛选DataFrame符合条件的行?
按分组四分位数筛选DataFrame行的解决方案
你之前的代码无效是因为Q1和Q4(实际是上四分位数Q3)是分组后得到的Series,其索引是PP的取值,和原DataFrame的整数索引不匹配,无法直接逐行对应每个分组的四分位数。下面提供两种可行的解决方案:
方法一:分组后应用筛选函数
直接对每个PP分组定义筛选逻辑,保留符合条件的行:
import pandas as pd import numpy.random as rnd # 生成原始DataFrame pp_employee_combinations = [(pp, name) for pp in range(1, 27) for name in ['Wyatt', 'Thom', 'Pete', 'Sue', 'Dave']] df = pd.DataFrame(pp_employee_combinations, columns=['PP', 'Name']) df['Hours per action'] = rnd.randint(10, 100, size=df.shape[0]) # 定义分组筛选函数 def filter_group_outliers(group): q1 = group['Hours per action'].quantile(0.25) q3 = group['Hours per action'].quantile(0.75) # 保留小于Q1或大于Q3的行 return group[(group['Hours per action'] < q1) | (group['Hours per action'] > q3)] # 按PP分组应用筛选,重置索引 filtered_df = df.groupby('PP').apply(filter_group_outliers).reset_index(drop=True)
方法二:用transform映射分组四分位数到每行
先将每个分组的Q1和Q3映射到原DataFrame的对应行,再进行筛选:
import pandas as pd import numpy.random as rnd # 生成原始DataFrame pp_employee_combinations = [(pp, name) for pp in range(1, 27) for name in ['Wyatt', 'Thom', 'Pete', 'Sue', 'Dave']] df = pd.DataFrame(pp_employee_combinations, columns=['PP', 'Name']) df['Hours per action'] = rnd.randint(10, 100, size=df.shape[0]) # 为每行添加对应PP分组的Q1和Q3 df['group_q1'] = df.groupby('PP')['Hours per action'].transform(lambda x: x.quantile(0.25)) df['group_q3'] = df.groupby('PP')['Hours per action'].transform(lambda x: x.quantile(0.75)) # 筛选符合条件的行,移除临时列 filtered_df = df[(df['Hours per action'] < df['group_q1']) | (df['Hours per action'] > df['group_q3'])].drop(columns=['group_q1', 'group_q3'])
两种方法都能实现按分组四分位数筛选的需求,方法一更简洁,方法二可以保留中间计算的四分位数用于后续分析。
内容的提问来源于stack exchange,提问作者Britt
相关产品推荐
相关产品推荐

