如何在含多组Datetime-Value列的DataFrame中设置Datetime索引?
解决方案
首先假设你的DataFrame结构类似这样(模拟多组Datetime和Value列):
import pandas as pd import numpy as np # 模拟测试数据 df = pd.DataFrame({ 'Datetime1': pd.date_range('2024-01-01 00:00:00', periods=5, freq='2S'), 'Value1': [10, 20, 30, 40, 50], 'Datetime2': pd.date_range('2024-01-01 00:00:01', periods=3, freq='3S'), 'Value2': [100, 200, 300], 'Datetime3': pd.date_range('2024-01-01 00:00:00', periods=4, freq='1S'), 'Value3': [5, 15, 25, 35] })
情况1:指定Datetime列作为索引,对齐所有Value列并填充缺失值
实现逻辑:
- 拆分每组
Datetime-Value为独立的时间序列 - 选定目标Datetime列(最长/最短均可)的时间点作为统一索引
- 将所有Value序列重新映射到目标索引,用
ffill()填充缺失值(取最后一次有效记录) - 合并所有对齐后的序列得到最终结果
代码实现:
def align_to_target_datetime(df, target_datetime_col): # 提取所有Datetime和对应Value列 datetime_cols = [col for col in df.columns if col.startswith('Datetime')] value_cols = [col for col in df.columns if col.startswith('Value')] # 生成目标索引(去重并排序) target_index = df[target_datetime_col].drop_duplicates().sort_values() # 逐个处理Value列,对齐到目标索引 aligned_series = [] for dt_col, val_col in zip(datetime_cols, value_cols): # 转换为Datetime索引的Series s = df.set_index(dt_col)[val_col].drop_duplicates() # 重索引并填充缺失值 aligned_s = s.reindex(target_index, method='ffill') aligned_series.append(aligned_s) # 合并结果并设置列名 result = pd.concat(aligned_series, axis=1) result.columns = value_cols return result # 示例1:用最长的Datetime3作为索引 aligned_long = align_to_target_datetime(df, 'Datetime3') print("以最长Datetime列为索引的结果:") print(aligned_long) # 示例2:用最短的Datetime2作为索引 aligned_short = align_to_target_datetime(df, 'Datetime2') print("\n以最短Datetime列为索引的结果:") print(aligned_short)
情况2:选择较短的Datetime列作为索引,删除其他组的多余行
实现逻辑:
- 选定较短的Datetime列作为基准时间集合
- 对每组
Datetime-Value,只保留时间点存在于基准集合中的行 - 合并所有筛选后的组,以基准Datetime为索引
代码实现:
def filter_to_shortest_datetime(df, short_datetime_col): # 获取基准时间点集合 base_times = set(df[short_datetime_col].drop_duplicates()) datetime_cols = [col for col in df.columns if col.startswith('Datetime')] value_cols = [col for col in df.columns if col.startswith('Value')] # 逐个筛选每组的有效行 filtered_dfs = [] for dt_col, val_col in zip(datetime_cols, value_cols): # 保留时间点在基准集合内的行 filtered = df[df[dt_col].isin(base_times)][[dt_col, val_col]] # 重命名Datetime列,方便后续合并 filtered = filtered.rename(columns={dt_col: short_datetime_col}) filtered_dfs.append(filtered) # 合并所有筛选结果,以基准Datetime为索引 result = pd.merge(filtered_dfs[0], filtered_dfs[1:], on=short_datetime_col, how='inner') result = result.set_index(short_datetime_col).sort_index() return result # 示例:用最短的Datetime2作为索引,删除多余行 filtered_result = filter_to_shortest_datetime(df, 'Datetime2') print("以较短Datetime列为索引并删除多余行的结果:") print(filtered_result)
关键说明:
drop_duplicates()用于处理可能存在的重复时间点method='ffill'实现向前填充缺失值,若需要用后续值填充可改用bfill()- 情况2中
inner merge确保只保留所有组共有的时间点,若允许部分组缺失可改用left merge
内容的提问来源于stack exchange,提问作者Perrupi
相关产品推荐
相关产品推荐

