Pandas保留Contact与Amount组合变更后的最新更新行
解决Pandas保留Contact-Amount组合变更后最新记录的问题
需求说明
需要保留每个Contact与Amount组合每次变更后的最新Last updated记录——即当同一个Contact的Amount发生变化,或者切换到其他Contact后又回到原Amount时,都要保留该段连续相同组合的最后一条记录。
现有DataFrame
Contact Amount Last updated 0 011000111 2 2023-01-01 1 011000111 2 2023-01-02 2 011000112 2 2023-01-03 3 011000112 2 2023-01-04 4 011000112 2 2023-01-06 5 011000111 2 2023-01-07 6 011000111 2 2023-01-09 7 011000111 3 2023-01-11
期望结果
Contact Amount Last updated 1 011000111 2 2023-01-02 4 011000112 2 2023-01-06 6 011000111 2 2023-01-09 7 011000111 3 2023-01-11
当前代码问题
原代码使用drop_duplicates(subset=['Contact','Amount'], keep='last'),只会保留每个Contact-Amount组合的全局最后一条记录,无法识别中间切换后再次出现的相同组合,导致丢失了011000111第一次连续Amount=2的最新记录(行1)。
原代码及错误输出:
import pandas as pd # create the dataframe data = {'Contact': ['011000111', '011000111', '011000112', '011000112', '011000112', '011000111', '011000111', '011000111'], 'Amount': [2, 2, 2, 2, 2, 2, 2, 3], 'Last updated': ['2023-01-01', '2023-01-02', '2023-01-03', '2023-01-04', '2023-01-06', '2023-01-07', '2023-01-09', '2023-01-11']} df = pd.DataFrame(data) # convert the "Last updated" column to a datetime type df['Last updated'] = pd.to_datetime(df['Last updated']) # sort the dataframe by the "Last updated" columns in ascending order df = df.sort_values(['Last updated'], ascending=True) # drop the duplicates based on the "Contact" column and keep the last occurrence result = df.drop_duplicates(subset=['Contact','Amount'], keep='last') print(result)
错误输出:
Contact Amount Last updated 4 011000112 2 2023-01-06 6 011000111 2 2023-01-09 7 011000111 3 2023-01-11
解决方案
核心思路是识别连续相同的Contact-Amount组合,保留每组的最后一条记录:
- 对比当前行与上一行的Contact和Amount是否一致,标记组的起始点
- 根据标记生成连续分组ID
- 按分组ID聚合,取每组的最后一行
完整代码:
import pandas as pd # 创建原始数据 data = {'Contact': ['011000111', '011000111', '011000112', '011000112', '011000112', '011000111', '011000111', '011000111'], 'Amount': [2, 2, 2, 2, 2, 2, 2, 3], 'Last updated': ['2023-01-01', '2023-01-02', '2023-01-03', '2023-01-04', '2023-01-06', '2023-01-07', '2023-01-09', '2023-01-11']} df = pd.DataFrame(data) # 转换日期格式并按时间排序 df['Last updated'] = pd.to_datetime(df['Last updated']) df = df.sort_values('Last updated', ascending=True).reset_index(drop=True) # 标记连续相同Contact-Amount组合的分组 df['group'] = (df[['Contact', 'Amount']] != df[['Contact', 'Amount']].shift()).any(axis=1).cumsum() # 按分组取最后一行 result = df.groupby('group').last().reset_index(drop=True) print(result)
运行结果
Contact Amount Last updated 0 011000111 2 2023-01-02 1 011000112 2 2023-01-06 2 011000111 2 2023-01-09 3 011000111 3 2023-01-11
内容的提问来源于stack exchange,提问作者chaoszx
相关产品推荐
相关产品推荐

