如何修剪Pandas多层索引数据集以对齐时间范围与间隙?
问题描述
我有一个Pandas多层索引数据集,一级索引为Date,二级索引为TagId,可通过df.loc['01/06/2022'].loc['0x24025F44AD21'][...]访问数据。数据集片段如下:
X Y Time Date TagId 01/06/2022 0x24025F44AD21 3.121672 5.188564 1900-01-01 08:37:17.000 0x24025F44AD21 3.121672 5.188564 1900-01-01 08:37:17.200 0x24025F44AD21 3.121672 5.188564 1900-01-01 08:37:17.400 0x24025F44AD21 3.121672 5.188564 1900-01-01 08:37:17.600 0x24025F44AD21 3.121672 5.188564 1900-01-01 08:37:17.800 ... ... ... 0x24025F44AD21 [......] [......] 1900-01-01 11:59:26.400 0x24046130B076 [......] [......] 1900-01-01 08:58:10.200 ... ... ... 0x24046130B076 7.611438 2.346377 1900-01-01 12:31:05.800 0x24046130B076 7.611438 2.346377 1900-01-01 12:31:06.000 0x24046130B076 7.533170 2.035381 1900-01-01 12:31:06.200 0x24046130B076 7.533170 2.035381 1900-01-01 12:31:06.400
需要实现两个核心需求:
- 时间范围对齐:找到所有组中最晚的起始时间和最早的结束时间,用这个统一的时间窗口修剪所有组的数据。
- 测量间隙同步:让所有组的
Time序列完全一致,包括原数据中的测量间隙也要同步对齐(即某个时间点只要有一个组存在,所有组都要保留该时间点,缺失的X/Y值可留空或填充)。
最终输出的数据集结构如下:
X Y Time Date TagId 01/06/2022 0x24025F44AD21 [......] [......] 1900-01-01 08:58:10.200 ... ... ... 0x24025F44AD21 [......] [......] 1900-01-01 11:59:26.400 0x24046130B076 [......] [......] 1900-01-01 08:58:10.200 ... ... ... 0x24046130B076 [......] [......] 1900-01-01 11:59:26.400
解决方案
步骤1:转换Time列为datetime类型
先确保Time列是Pandas可识别的datetime格式,否则无法进行时间运算:
import pandas as pd df['Time'] = pd.to_datetime(df['Time'])
步骤2:计算全局统一时间窗口
按TagId分组,统计每个组的首尾时间,再从中提取所有组的最晚起始时间和最早结束时间:
# 按TagId分组,获取每个组的最小/最大时间 group_time_stats = df.groupby(level='TagId')['Time'].agg(['min', 'max']) # 全局最晚起始时间、最早结束时间 global_start = group_time_stats['min'].max() global_end = group_time_stats['max'].min()
步骤3:修剪数据到全局时间窗口
筛选出所有在全局窗口范围内的行:
df_trimmed = df[(df['Time'] >= global_start) & (df['Time'] <= global_end)]
步骤4:同步所有组的Time序列(对齐间隙)
提取全局窗口内所有唯一的时间点,然后让每个TagId组都按这个时间序列重新索引,实现间隙对齐:
# 提取并排序全局窗口内的所有唯一时间点 global_time_sequence = df_trimmed['Time'].unique() global_time_sequence.sort() # 按TagId分组,重新索引到全局时间序列 df_aligned = df_trimmed.groupby(level='TagId').apply( lambda g: g.set_index('Time').reindex(global_time_sequence).reset_index() ).reset_index(level=0, drop=True) # 恢复原多层索引结构 df_aligned = df_aligned.set_index(['Date', 'TagId', 'Time']).sort_index()
补充说明
- 重新索引后缺失的X/Y值会填充为
NaN,如果需要自定义填充值,可在reindex中添加fill_value参数,比如reindex(global_time_sequence, fill_value=0)。 - 如果数据包含多个
Date,只需将分组level改为['Date', 'TagId'],重复上述步骤即可按日期分别对齐。
内容的提问来源于stack exchange,提问作者Job
相关产品推荐
相关产品推荐

