Pandas:如何为所有外层索引补全统一的内层时间戳索引行
问题分析
你当前的reindex方法无效,核心原因是原数据集的索引是多级索引(id, ts),但你仅传入了单级的timestamps列表。Pandas只会尝试匹配索引中的ts级别,不会自动为每个id生成所有timestamps的组合,因此结果行数和原数据一致。
最佳实践
要实现每个id都拥有所有统一的timestamps,核心是生成id与timestamps的笛卡尔积索引,再用这个完整索引重新对齐原数据。以下是两种常用方法:
方法1:生成完整多级索引后Reindex
先提取所有唯一的id和timestamps,通过MultiIndex.from_product生成所有可能的(id, ts)组合,再用这个索引对原DataFrame重索引:
import numpy as np import pandas as pd # 原数据构建 df = pd.DataFrame(columns = ["id", "ts", "value"]) df.loc[0,:] = [1, pd.Timestamp("2022-01-01 00:00:00"), 1] df.loc[1,:] = [1, pd.Timestamp("2022-01-01 00:00:01"), 2] df.loc[2,:] = [2, pd.Timestamp("2022-01-01 00:00:00"), 3] df = df.set_index(["id", "ts"]) # 提取所有唯一id和timestamps unique_ids = df.index.get_level_values("id").unique() all_timestamps = df.index.get_level_values("ts").unique().sort_values() # 生成完整的多级索引 full_index = pd.MultiIndex.from_product( [unique_ids, all_timestamps], names=["id", "ts"] ) # 重索引 df2 = df.reindex(full_index, fill_value=np.nan)
执行后df2会有4行:id=1的两个timestamps记录,id=2的两个timestamps记录(其中id=2的00:00:01对应的value为NaN)。
方法2:Unstack + Stack 转换
通过unstack将ts级别转为列,此时每个id会自动填充所有timestamps列(缺失值为NaN),再用stack将列转回索引级别,实现更简洁:
# 基于原df操作 df2 = df.unstack(level="ts").stack(dropna=False)
这种方法的结果和方法1完全一致,适合快速实现需求。
补充说明
如果后续需要按固定频率重采样(比如每秒、每分钟),可以先对每个id分组后使用resample,自动生成对应频率的完整时间序列:
df2 = df.groupby("id").resample("S", level="ts").asfreq()
这里的"S"代表按秒重采样,会为每个id生成每秒的记录,缺失值自动填充NaN。
内容的提问来源于stack exchange,提问作者Brian Burrows
相关产品推荐
相关产品推荐

