如何使用Pandas移除上方含'Out'标记的重复DataFrame行?
用Pandas处理带"In/Out"标记的去重需求
原始DataFrame
import pandas as pd df = pd.DataFrame([['In', 'Age', 'Nat.'], ['Jakub Kiwior', 22, 'Poland'], ['Leandro Trossard', 28, 'Belgium'], ['Jorginho', 31, 'Italy'], ['Out', 'Age', 'Nat.'], ['Jhon Durán', 19, 'Colombia'], ['In', 'Age', 'Nat.'], ['Jhon Durán', 19, 'Colombia'], ['Álex Moreno', 29, 'Spain'], ['Out', 'Age', 'Nat.'], ['Leandro Trossard', 28, 'Belgium'], ['Jorginho', 31, 'Italy'], ['In', 'Age', 'Nat.'], ['Out', 'Age', 'Nat.'], ['In', 'Age', 'Nat.'], ], columns=['Player', 'Age', 'Nat.'])
需求说明
需要移除满足以下条件的行:
- 该行是球员数据(
Player列值不是"In"或"Out") - 该行最近上方的标记行(距离最近的
Player值为"In"/"Out"的行)是"Out" - 该球员已经在之前的行中出现过
比如:
- "Out"行后的第一个"Jhon Durán"需要移除(首次出现于Out区)
- "Out"行后的"Leandro Trossard"和"Jorginho"需要移除(此前在In区已出现)
- "In"行后的"Jhon Durán"则保留(属于In区的重复项)
实现代码
# 1. 给每行标记最近的上方标记(In/Out),用向下填充实现 df['last_mark'] = df['Player'].where(df['Player'].isin(['In', 'Out'])).ffill() # 2. 记录每个球员首次出现的索引位置 player_first_indices = df[~df['Player'].isin(['In', 'Out'])]['Player'].drop_duplicates(keep='first').index # 3. 生成需要移除的行的掩码:Out区的非首次出现球员行 remove_mask = df.apply( lambda row: (row['Player'] not in ['In', 'Out']) and (row['last_mark'] == 'Out') and (row.name not in player_first_indices), axis=1 ) # 4. 过滤得到最终结果 result_df = df[~remove_mask].reset_index(drop=True) # 打印结果 print(result_df)
最终输出
Player Age Nat. last_mark 0 In Age Nat. In 1 Jakub Kiwior 22 Poland In 2 Leandro Trossard 28 Belgium In 3 Jorginho 31 Italy In 4 Out Age Nat. Out 5 In Age Nat. In 6 Jhon Durán 19 Colombia In 7 Álex Moreno 29 Spain In 8 Out Age Nat. Out 9 In Age Nat. In 10 Out Age Nat. Out 11 In Age Nat. In
内容的提问来源于stack exchange,提问作者code_machine
相关产品推荐
相关产品推荐

