如何基于列值从按Days和ID分组的DataFrame中删除行?
按Days和ID分组删除DataFrame中符合条件的行
需求说明
对DataFrame按Days和ID两列分组后,每组内删除同时满足以下三个条件的行:
Car3的值为nan- 当前行的
Car1等于组内另一行的Car2 - 当前行的
Car2等于组内另一行的Car3
示例DataFrame
import pandas as pd import numpy as np df = pd.DataFrame({'Days':[5,5,5,5,6,6], 'ID':['A11','A11','A11','A11','B12','B12'], 'Country':['DE','DE','FR','US','US','US'], 'Car1':['BMW','Volvo','Audi','BMW','Mercedes','BMW'], 'Car2':['Volvo','Mercedes','BMW','Volvo','Volvo','Volvo'], 'Car3':['Mercedes',np.nan,'Volvo',np.nan,np.nan,np.nan]})
对应表格:
| Days | ID | Country | Car1 | Car2 | Car3 | |
|---|---|---|---|---|---|---|
| 0 | 5 | A11 | DE | BMW | Volvo | Mercedes |
| 1 | 5 | A11 | DE | Volvo | Mercedes | NaN |
| 2 | 5 | A11 | FR | Audi | BMW | Volvo |
| 3 | 5 | A11 | US | BMW | Volvo | NaN |
| 4 | 6 | B12 | US | Mercedes | Volvo | NaN |
| 5 | 6 | B12 | US | BMW | Volvo | NaN |
解决方案代码
def filter_group(group): # 提取组内非空的Car2、Car3值集合,用于快速匹配判断 group_car2 = set(group['Car2'].dropna()) group_car3 = set(group['Car3'].dropna()) # 构建保留行的掩码:不满足三个删除条件的行 mask = ~( (group['Car3'].isna()) & (group['Car1'].isin(group_car2)) & (group['Car2'].isin(group_car3)) ) return group[mask] # 按Days和ID分组应用过滤逻辑 filtered_df = df.groupby(['Days', 'ID'], group_keys=False).apply(filter_group)
处理后结果
执行以下代码查看结果:
print(filtered_df.reset_index(drop=True))
输出表格:
| Days | ID | Country | Car1 | Car2 | Car3 | |
|---|---|---|---|---|---|---|
| 0 | 5 | A11 | DE | BMW | Volvo | Mercedes |
| 1 | 5 | A11 | FR | Audi | BMW | Volvo |
| 2 | 6 | B12 | US | Mercedes | Volvo | NaN |
| 3 | 6 | B12 | US | BMW | Volvo | NaN |
代码说明
- 分组过滤函数
filter_group:- 先收集组内所有非空的
Car2和Car3值,用集合存储提升匹配效率 - 通过掩码反向筛选,排除同时满足三个删除条件的行
- 先收集组内所有非空的
- 利用
groupby按指定列分组,将过滤函数应用到每个分组,最终得到目标DataFrame
内容的提问来源于stack exchange,提问作者the phoenix
相关产品推荐
相关产品推荐

