如何用Pandas GroupBy按最新行的Serial值更新组内所有行?
按ID分组替换Pandas DataFrame的Serial列
需求说明
给定包含id、location、serial、valid_from、valid_to列的Pandas DataFrame,需按id分组,将每组内所有行的serial列值替换为该组中valid_from日期最新的行的serial值。因数据中id数量庞大,需采用高效的GroupBy方案实现。
原始数据构建
import pandas as pd import numpy as np df = pd.DataFrame( data=[ ['X', 'L1', 'S2', '2023-06-26', '2023-06-27'], ['X', 'L2', 'S2', '2023-06-27', '9999-01-01'], ['X', 'L2', 'S2', '2023-06-28', np.nan] ], columns=['id', 'location', 'serial', 'valid_from', 'valid_to'] )
实现步骤
转换日期列类型
先将valid_from转换为datetime类型,确保能正确比较日期先后:df['valid_from'] = pd.to_datetime(df['valid_from'])提取每组最新日期对应的Serial值
通过sort_values和groupby组合,高效获取每个id组内valid_from最新的行的serial值:# 按日期升序排序后,每组最后一行即为日期最新的记录 latest_serial = df.sort_values('valid_from').groupby('id')['serial'].last()替换原DataFrame的Serial列
用map方法将每组对应的最新serial值映射回原DataFrame:df['serial'] = df['id'].map(latest_serial)
效果验证
若修改测试数据,将第三行的serial改为S3:
df_test = pd.DataFrame( data=[ ['X', 'L1', 'S2', '2023-06-26', '2023-06-27'], ['X', 'L2', 'S2', '2023-06-27', '9999-01-01'], ['X', 'L2', 'S3', '2023-06-28', np.nan] ], columns=['id', 'location', 'serial', 'valid_from', 'valid_to'] ) df_test['valid_from'] = pd.to_datetime(df_test['valid_from']) latest_serial_test = df_test.sort_values('valid_from').groupby('id')['serial'].last() df_test['serial'] = df_test['id'].map(latest_serial_test) print(df_test)
输出结果:
id location serial valid_from valid_to 0 X L1 S3 2023-06-26 2023-06-27 1 X L2 S3 2023-06-27 9999-01-01 2 X L2 S3 2023-06-28 NaN
可见同一id下所有行的serial都被替换为该组最新日期对应的S3。
方案优势
该方案基于Pandas原生的GroupBy和map操作,避免了低效的循环遍历,能够高效处理包含大量id的数据集,保证运算性能。
内容的提问来源于stack exchange,提问作者user3235169
相关产品推荐
相关产品推荐

