分组条件筛选行:基于A组构建新DataFrame df1的技术需求
解决方案:Pandas分组筛选指定行
我来给你搞定这个分组筛选的需求,用Pandas的分组+自定义函数就能完美实现,咱们直接上代码加解释:
思路拆解
核心是对A列的每个分组(blue/green)执行两步筛选:
- 直接提取B等于C的行;
- 优先提取B等于C-1的行,若不存在则选B小于C-1且最接近该值的行(也就是B最大的那行)。
代码实现
先模拟一个符合你需求的示例DataFrame,然后写处理逻辑:
import pandas as pd # 模拟你的原始数据(可替换成你实际的df) data = { 'A': ['blue', 'blue', 'blue', 'green', 'green', 'green'], 'B': [10.0, 12.0, 14.0, 8.0, 9.0, 10.0], 'C': [14.0, 14.0, 14.0, 10.0, 10.0, 10.0] } df = pd.DataFrame(data) def process_single_group(group): # 第一步:筛选B=C的行 part1 = group[group['B'] == group['C']].copy() # 第二步:处理B=C-1或最接近的情况 # 假设每组的C值是统一的(从你的例子来看是这样),取组内第一个C值作为基准 c_base = group['C'].iloc[0] target_b = c_base - 1 # 筛选出B小于等于target_b的候选行 candidate_rows = group[group['B'] <= target_b] part2 = pd.DataFrame() # 默认空,避免报错 if not candidate_rows.empty: # 选B最大的行(最接近target_b) closest_row = candidate_rows.loc[[candidate_rows['B'].idxmax()]] part2 = closest_row # 合并两部分并去重(防止同一行同时满足两个条件) final_group = pd.concat([part1, part2]).drop_duplicates() return final_group # 按A列分组,应用自定义函数生成df1 df1 = df.groupby('A', group_keys=False).apply(process_single_group)
代码解释
- 自定义函数
process_single_group:专门处理单个分组的逻辑,可读性拉满; - 第一步筛选:直接用布尔索引
group['B'] == group['C']提取符合条件的行; - 第二步筛选:
- 先拿到分组的基准C值(如果你的数据中每组C不统一,可调整为按每行C单独处理);
- 计算目标B值
C-1,然后筛选出B不超过该目标的行; - 从候选行里挑B最大的(也就是最接近目标的),如果没有候选行就跳过这部分;
- 合并去重:避免同一行被两次选中(比如某行同时满足B=C和B=C-1,不过这种情况只有C=1才会出现)。
测试结果
用上面的模拟数据跑出来的df1会是:
| A | B | C | |
|---|---|---|---|
| 2 | blue | 14.0 | 14.0 |
| 1 | blue | 12.0 | 14.0 |
| 5 | green | 10.0 | 10.0 |
| 4 | green | 9.0 | 10.0 |
完全符合你的需求:blue组选了B=14(等于C)和B=12(最接近13=C-1);green组选了B=10(等于C)和B=9(等于C-1)。
内容的提问来源于stack exchange,提问作者Tie_24




