多源时间序列数据缺失值处理求助(Pandas resample不适用)
解决方案:保留原始时间戳的多源时间序列对齐
针对多数据源时间戳不一致导致的缺失值问题,resample因生成固定频率的冗余时间点不符合需求,推荐以下基于原始时间戳对齐的方案:
核心思路
仅保留所有数据源的原始时间戳,不对齐到固定频率,仅填充现有时间点上的缺失值,避免生成不必要的行。
步骤1:数据预处理(转换时间戳类型)
首先确保时间戳列是datetime类型,否则无法进行时间相关操作:
import pandas as pd # 示例数据初始化(实际场景可替换为pd.read_csv等读取外部数据的方法) data = [ ["2023-01-01 00:00:00.000", "Value", pd.NA, pd.NA], ["2023-01-01 00:00:00.050", "Value", pd.NA, pd.NA], ["2023-01-01 00:00:00.150", pd.NA, "Value", "Value"], ["2023-01-01 05:00:00.450", pd.NA, "Value", "Value"], ["2023-01-01 05:00:00.500", "Value", pd.NA, pd.NA], ] df = pd.DataFrame(data, columns=["Timestamp", "Variable A", "Variable B", "Variable C"]) # 转换为datetime类型 df["Timestamp"] = pd.to_datetime(df["Timestamp"])
步骤2:对齐并填充缺失值
方案A:基于合并后的DataFrame处理
如果数据已经合并为一个DataFrame,先按时间戳排序,再按时间间隔限制填充:
# 按时间戳排序 df = df.sort_values("Timestamp").reset_index(drop=True) # 计算相邻时间戳的间隔(秒) df["time_interval"] = df["Timestamp"].diff().dt.total_seconds() # 仅填充时间间隔小于阈值的缺失值(示例阈值设为1秒,可根据业务调整) # 填充Variable A mask_a = df["Variable A"].isna() & (df["time_interval"] < 1) df.loc[mask_a, "Variable A"] = df["Variable A"].ffill() # 填充Variable B和C mask_bc = df[["Variable B", "Variable C"]].isna().any(axis=1) & (df["time_interval"] < 1) df.loc[mask_bc, ["Variable B", "Variable C"]] = df[["Variable B", "Variable C"]].ffill() # 移除辅助列 df = df.drop("time_interval", axis=1)
方案B:拆分数据源后合并(更适合多数据源场景)
如果原始数据是多个独立的数据源文件,先分别读取处理,再合并所有原始时间戳:
# 拆分各数据源(实际场景中可分别读取不同文件) df_a = df[["Timestamp", "Variable A"]].dropna().set_index("Timestamp") df_bc = df[["Timestamp", "Variable B", "Variable C"]].dropna().set_index("Timestamp") # 合并所有原始时间戳,保留所有时间点 combined_df = pd.concat([df_a, df_bc], axis=1).sort_index() # 计算时间间隔并填充小间隔缺失值 time_interval = combined_df.index.to_series().diff().dt.total_seconds() # 填充Variable A combined_df["Variable A"] = combined_df["Variable A"].where( ~(combined_df["Variable A"].isna() & (time_interval < 1)), combined_df["Variable A"].ffill() ) # 填充Variable B和C combined_df[["Variable B", "Variable C"]] = combined_df[["Variable B", "Variable C"]].where( ~(combined_df[["Variable B", "Variable C"]].isna().any(axis=1) & (time_interval < 1)), combined_df[["Variable B", "Variable C"]].ffill() ) # 重置索引恢复Timestamp列 combined_df = combined_df.reset_index()
关键说明
- 避免使用
resample:该方法会强制生成固定频率的时间点,导致大时间间隔之间出现大量冗余空行,不符合需求。 - 填充阈值可调整:示例中用1秒作为间隔阈值,可根据业务场景(比如传感器采样频率)调整为合适的数值,避免跨大时间间隔的不合理填充。
- 填充方式可选:除了
ffill(向前填充),还可根据需求使用bfill(向后填充)或interpolate(method='time')(时间插值),同样可结合时间间隔限制使用。
内容的提问来源于stack exchange,提问作者guir
相关产品推荐
相关产品推荐

