如何在Pandas中按ID保留最新行并替换modify类型为对应非修改类型
Pandas数据处理:按ID保留最新行并替换modify类型值
问题说明
输入DataFrame:
id time type 1 t1 create 1 t2 modify 2 t3 modify 2 t4 deploy 3 t5 delete
规则与需求:
time值递增(t2比t1新,依此类推)- 若某ID的
type存在modify,则该ID必有且仅有一行非modify类型记录;无modify的ID仅一行非modify记录 - 最终处理逻辑:
- 无
modify记录的ID:直接保留原行 - 有
modify记录的ID:保留该ID时间最新的行;若最新行的type是modify,则将其替换为同ID的非modify类型值,删除旧行
- 无
期望输出:
id time type 1 t2 create 2 t4 deploy 3 t5 delete
用户当前实现了按ID保留最新行,但未完成modify类型的替换逻辑,现有代码片段:
df.loc[df.groupby('id')['time'].idxmax(), type != modify]
解决方案
方法一:分组提取+类型替换
import pandas as pd # 构造示例数据(实际使用时替换为你的DataFrame) data = { 'id': [1, 1, 2, 2, 3], 'time': ['t1', 't2', 't3', 't4', 't5'], 'type': ['create', 'modify', 'modify', 'deploy', 'delete'] } df = pd.DataFrame(data) # 1. 提取每个ID对应的非modify类型值 non_modify_map = df[df['type'] != 'modify'].set_index('id')['type'] # 2. 获取每个ID的最新行 latest_records = df.loc[df.groupby('id')['time'].idxmax()].set_index('id') # 3. 替换modify类型为对应非modify值 latest_records['type'] = latest_records.apply( lambda row: non_modify_map[row.name] if row['type'] == 'modify' else row['type'], axis=1 ) # 重置索引得到最终结果 final_result = latest_records.reset_index() print(final_result)
方法二:合并数据框实现替换
import pandas as pd df = pd.DataFrame({ 'id': [1, 1, 2, 2, 3], 'time': ['t1', 't2', 't3', 't4', 't5'], 'type': ['create', 'modify', 'modify', 'deploy', 'delete'] }) # 提取非modify类型记录并改名 non_modify_df = df[df['type'] != 'modify'].rename(columns={'type': 'target_type'}) # 获取每个ID的最新行 latest_df = df.loc[df.groupby('id')['time'].idxmax()] # 合并数据,替换modify类型 merged = pd.merge(latest_df, non_modify_df[['id', 'target_type']], on='id', how='left') merged['type'] = merged.apply(lambda x: x['target_type'] if x['type'] == 'modify' else x['type'], axis=1) # 清理多余列,得到结果 final_result = merged.drop('target_type', axis=1) print(final_result)
代码说明
- 两种方法核心逻辑一致:先获取每个ID的非
modify类型值,再获取最新行,最后判断并替换类型 - 利用题目给定的“有modify的ID必有唯一非modify值”的规则,无需处理多值情况
- 保持了最新行的
time值,只替换type列的内容
内容的提问来源于stack exchange,提问作者Robert Luse
相关产品推荐
相关产品推荐

