高效优化:移除Pandas DataFrame中基于次新time_1的指定行
高效处理Pandas DataFrame的时间过滤需求
直接上高效的向量化解决方案,完全避免循环,利用Pandas的分组和transform能力提升性能:
步骤1:确保时间列格式正确
如果你的time_1和time_2还不是datetime类型,先做转换:
import pandas as pd # 转换为datetime类型(如果需要) df['time_1'] = pd.to_datetime(df['time_1']) df['time_2'] = pd.to_datetime(df['time_2'])
步骤2:计算每个ID的次大time_1值
用分组+transform,给每行标记对应ID的次新time_1值(如果存在):
def get_second_latest_time(group): # 获取当前ID下所有唯一的time_1,按从新到旧排序 unique_times = sorted(group.unique(), reverse=True) # 有至少2个不同time_1时返回次新值,否则返回空时间(NaT) return unique_times[1] if len(unique_times) >= 2 else pd.NaT # 给每行添加对应ID的次新time_1标记 df['second_latest_time1'] = df.groupby('ID')['time_1'].transform(get_second_latest_time)
步骤3:过滤行
根据标记过滤:如果ID只有一个time_1(即second_latest_time1为NaT),保留所有行;否则只保留time_2不早于次新time_1的行:
# 过滤逻辑 filtered_df = df[ df['second_latest_time1'].isna() | (df['time_2'] >= df['second_latest_time1']) ].drop(columns=['second_latest_time1'])
示例验证
假设原数据如下:
| ID | time_1 | time_2 |
|---|---|---|
| 1 | 2023-10-01 10:00:00 | 2023-09-30 09:00:00 |
| 1 | 2023-10-02 11:00:00 | 2023-10-01 12:00:00 |
| 1 | 2023-10-03 12:00:00 | 2023-10-02 13:00:00 |
| 2 | 2023-09-01 08:00:00 | 2023-08-31 07:00:00 |
| 2 | 2023-09-01 08:00:00 | 2023-09-01 09:00:00 |
处理后得到的filtered_df结果:
| ID | time_1 | time_2 |
|---|---|---|
| 1 | 2023-10-02 11:00:00 | 2023-10-01 12:00:00 |
| 1 | 2023-10-03 12:00:00 | 2023-10-02 13:00:00 |
| 2 | 2023-09-01 08:00:00 | 2023-08-31 07:00:00 |
| 2 | 2023-09-01 08:00:00 | 2023-09-01 09:00:00 |
性能说明
这个方案用Pandas原生的分组和transform操作,内部是C优化的向量化计算,相比Python循环,在大数据量下性能提升非常显著——数据量越大,优势越明显。
内容的提问来源于stack exchange,提问作者Frede
相关产品推荐
相关产品推荐

