Python-Pandas中基于分组列与行级比较生成重复标记列
基于Pandas分组和重复标记生成新列Only_Dupes
我在处理Pandas DataFrame时遇到了一个需求,需要根据现有的IsDuplicate字段、Loc分组和Category字段生成新列Only_Dupes,希望能得到帮助。
原始数据
我的DataFrame是通过pandas.DataFrame.duplicated()生成的IsDuplicate字段,逻辑是按Loc分组,基于Category标记重复记录(首次出现为False,重复出现为True)。原始数据如下:
| Number | Loc | Category | Date | IsDuplicate |
|---|---|---|---|---|
| 1 | A | jetski | 01/01/2020 | False |
| 2 | A | kayak | 01/02/2020 | False |
| 3 | A | jetski,kayak | 01/04/2020 | False |
| 4 | B | jetski | 01/05/2020 | False |
| 5 | B | jetski | 01/07/2020 | True |
| 6 | C | kayak | 01/08/2020 | False |
| 7 | C | kayak | 01/09/2020 | True |
| 8 | C | jetski | 01/10/2020 | False |
需求规则
按Loc分组后,生成Only_Dupes列的规则如下:
- 若分组内存在
IsDuplicate为True的记录:- 对于当前行的
Category,如果该Category在分组内有重复(即存在IsDuplicate=True的行),则Only_Dupes等于该行的IsDuplicate值; - 如果当前行的
Category在分组内没有重复(所有该行Category的IsDuplicate都是False),则标记为'Not Applicable';
- 对于当前行的
- 若分组内所有记录的
IsDuplicate都是False,则所有行的Only_Dupes都标记为'Not Applicable'。
预期输出
最终想要的结果如下:
| Number | Loc | Category | Date | IsDuplicate | Only_Dupes |
|---|---|---|---|---|---|
| 1 | A | jetski | 01/01/2020 | False | Not Applicable |
| 2 | A | kayak | 01/02/2020 | False | Not Applicable |
| 3 | A | jetski,kayak | 01/04/2020 | False | Not Applicable |
| 4 | B | jetski | 01/05/2020 | False | False |
| 5 | B | jetski | 01/07/2020 | True | True |
| 6 | C | kayak | 01/08/2020 | False | False |
| 7 | C | kayak | 01/09/2020 | True | True |
| 8 | C | jetski | 01/10/2020 | False | Not Applicable |
解决方案
可以通过Pandas的groupby结合transform来实现这个逻辑,步骤如下:
- 首先,对每个
Loc分组,计算每个Category是否存在重复(即该Category下有IsDuplicate=True的记录); - 然后,根据分组是否有重复记录、当前
Category是否有重复,来赋值Only_Dupes列。
具体代码如下:
import pandas as pd # 构造原始数据 data = { 'Number': [1,2,3,4,5,6,7,8], 'Loc': ['A','A','A','B','B','C','C','C'], 'Category': ['jetski','kayak','jetski,kayak','jetski','jetski','kayak','kayak','jetski'], 'Date': ['01/01/2020','01/02/2020','01/04/2020','01/05/2020','01/07/2020','01/08/2020','01/09/2020','01/10/2020'], 'IsDuplicate': [False,False,False,False,True,False,True,False] } df = pd.DataFrame(data) # 步骤1:按Loc和Category分组,标记每个Category是否有重复(即存在IsDuplicate=True) df['has_dupe_cat'] = df.groupby(['Loc', 'Category'])['IsDuplicate'].transform(lambda x: x.any()) # 步骤2:按Loc分组,标记该分组是否存在任何重复记录 df['group_has_dupe'] = df.groupby('Loc')['IsDuplicate'].transform(lambda x: x.any()) # 步骤3:根据规则生成Only_Dupes列 df['Only_Dupes'] = df.apply( lambda row: row['IsDuplicate'] if row['group_has_dupe'] and row['has_dupe_cat'] else 'Not Applicable', axis=1 ) # 可选:删除中间辅助列 df = df.drop(['has_dupe_cat', 'group_has_dupe'], axis=1) print(df)
运行这段代码后,就能得到符合预期的Only_Dupes列。
代码说明
has_dupe_cat:标记当前行的Category在同一Loc下是否存在重复记录;group_has_dupe:标记当前Loc分组内是否存在任何重复记录;- 最后通过
apply函数,结合两个标记字段,按照规则给Only_Dupes赋值:当分组有重复且当前Category有重复时,取IsDuplicate的值,否则标记为Not Applicable。
内容的提问来源于stack exchange,提问作者nealkaps
相关产品推荐
相关产品推荐

