如何仅移除DataFrame列开头重复项并保留最后一个条目?
问题描述
我想绘制一个DataFrame,但各列存在若干重复条目。我希望仅保留每列开头重复段的最后一个条目,删除前面的重复内容(中间和末尾的重复项忽略),避免这些重复内容出现在图表中。
我尝试过的代码(但这段代码会移除整行重复项,不符合需求):
df = df.drop_duplicates(subset=df.columns[1:], keep='last') df = df.groupby((df.shift() != df).cumsum()).filter(lambda x: len(x) < 5)
输入数据
Date Build1 Build2 Build3 Build4 Build5 Build6 2022-11-26 00:00:00 30 30 30 30 30 30 2022-11-27 00:00:00 30 30 30 30 30 30 2022-11-28 00:00:00 30 30 30 30 30 30 2022-11-29 00:00:00 30 30 30 30 30 30 2022-11-30 00:00:00 30 30 30 30 30 30 2022-12-01 00:00:00 28 30 30 30 30 30 2022-12-02 00:00:00 25 30 30 30 30 30 2022-12-03 00:00:00 25 30 30 30 30 30 2022-12-04 00:00:00 22 28 30 30 30 30 2022-12-05 00:00:00 22 26 30 30 30 30 2022-12-06 00:00:00 22 23 30 30 30 30 2022-12-07 00:00:00 22 22 30 30 30 30 2022-12-08 00:00:00 22 20 30 30 30 30 2022-12-09 00:00:00 22 20 25 30 30 30 2022-12-10 00:00:00 22 20 23 30 30 30 2022-12-11 00:00:00 22 20 23 30 30 30 2022-12-12 00:00:00 22 20 18 30 30 30 2022-12-13 00:00:00 22 20 14 30 30 30 2022-12-14 00:00:00 22 20 11 30 30 30 2022-12-15 00:00:00 22 20 10 27 30 30 2022-12-16 00:00:00 22 20 10 20 30 30 2022-12-17 00:00:00 22 20 10 20 30 30 2022-12-18 00:00:00 22 20 10 20 30 30 2022-12-19 00:00:00 22 20 10 13 30 30 2022-12-20 00:00:00 22 20 10 2 30 30 2022-12-21 00:00:00 22 20 10 2 19 30 2022-12-22 00:00:00 22 20 10 2 11 30 2022-12-23 00:00:00 22 20 10 2 4 30 2022-12-24 00:00:00 22 20 10 2 0 30 2022-12-25 00:00:00 22 20 10 2 0 22 2022-12-26 00:00:00 22 20 10 2 0 15 2022-12-27 00:00:00 22 20 10 2 0 15 2022-12-28 00:00:00 22 20 10 2 0 9
期望输出
Date Build1 Build2 Build3 Build4 Build5 Build6 2022-11-26 00:00:00 2022-11-27 00:00:00 2022-11-28 00:00:00 2022-11-29 00:00:00 2022-11-30 00:00:00 30 2022-12-01 00:00:00 28 2022-12-02 00:00:00 25 2022-12-03 00:00:00 25 30 2022-12-04 00:00:00 22 28 2022-12-05 00:00:00 22 26 2022-12-06 00:00:00 22 23 2022-12-07 00:00:00 22 22 2022-12-08 00:00:00 22 20 30 2022-12-09 00:00:00 22 20 25 2022-12-10 00:00:00 22 20 23 2022-12-11 00:00:00 22 20 23 2022-12-12 00:00:00 22 20 18 2022-12-13 00:00:00 22 20 14 2022-12-14 00:00:00 22 20 11 30 2022-12-15 00:00:00 22 20 10 27 2022-12-16 00:00:00 22 20 10 20 2022-12-17 00:00:00 22 20 10 20 2022-12-18 00:00:00 22 20 10 20 2022-12-19 00:00:00 22 20 10 13 2022-12-20 00:00:00 22 20 10 2 30 2022-12-21 00:00:00 22 20 10 2 19 2022-12-22 00:00:00 22 20 10 2 11 2022-12-23 00:00:00 22 20 10 2 4 2022-12-24 00:00:00 22 20 10 2 0 30 2022-12-25 00:00:00 22 20 10 2 0 22 2022-12-26 00:00:00 22 20 10 2 0 15 2022-12-27 00:00:00 22 20 10 2 0 15 2022-12-28 00:00:00 22 20 10 2 0 9
解决方案
要实现每列仅保留开头重复段的最后一个条目,我们可以针对每一列单独处理,具体代码如下:
import pandas as pd # 假设你的DataFrame已经加载为df # 将Date列设为索引,方便后续行定位 df = df.set_index('Date') for col in df.columns: # 找到该列第一个与初始值不同的位置 first_change_idx = (df[col] != df[col].iloc[0]).idxmax() first_change_pos = df.index.get_loc(first_change_idx) # 如果整列值都相同,只保留最后一行,其余清空 if first_change_pos == len(df) - 1: df.loc[df.index[:-1], col] = '' else: # 清空开头重复段中除最后一行外的所有值 df.loc[df.index[:first_change_pos], col] = '' # 恢复Date列为普通列 df = df.reset_index()
代码说明
- 针对每一列,先定位第一个与初始值不同的位置,以此划分开头的重复段;
- 对开头重复段,仅保留最后一行的原始数值,其余行设为空字符串(如果需要用缺失值,可替换为
pd.NA); - 列中后续的重复内容(比如Build1在12-02到12-03的重复、Build3在12-10到12-11的重复)保持原样,完全符合需求。
运行这段代码后,就能得到你期望的输出结果,可直接用于绘图。
内容的提问来源于stack exchange,提问作者Pranav
相关产品推荐
相关产品推荐

