如何按时间戳合并多个Pandas DataFrame并减少数据丢失?
多DataFrame时间戳合并减少数据丢失方案
问题场景
现有代码可通过pd.merge_asof合并两个Pandas DataFrame:
mergedDF = pd.merge_asof(df1, df2, on="DateTime", tolerance=pd.Timedelta("7s"))
需合并4-5个DataFrame组成的列表,所有DataFrame的DateTime列均为30秒间隔但存在偏移(不完全匹配),其余列互不相同。
若依次执行如下合并:
mergedDF = pd.merge_asof(df1, df2, on="DateTime", tolerance=pd.Timedelta("7s")) mergedDF = pd.merge_asof(mergedDF, df3, on="DateTime", tolerance=pd.Timedelta("7s")) mergedDF = pd.merge_asof(mergedDF, df4, on="DateTime", tolerance=pd.Timedelta("7s")) mergedDF = pd.merge_asof(mergedDF, df5, on="DateTime", tolerance=pd.Timedelta("7s"))
最终结果仅保留df1的时间戳,大量其他DataFrame的有效数据丢失,需找到数据丢失最少的合并方案。
解决方案
方法1:基于全量时间戳的基准合并(数据丢失最少)
先收集所有DataFrame的时间戳作为基准,再将每个DataFrame匹配到基准时间戳上,最后合并结果:
import pandas as pd # df_list 为包含所有待合并DataFrame的列表 df_list = [df1, df2, df3, df4, df5] # 1. 收集所有唯一时间戳并排序,生成基准DataFrame all_timestamps = pd.concat([df["DateTime"] for df in df_list]).drop_duplicates().sort_values().reset_index(drop=True) base_df = pd.DataFrame({"DateTime": all_timestamps}) # 2. 将每个DataFrame与基准时间戳做merge_asof匹配 merged_results = [base_df] for df in df_list: # 必须确保DateTime列已排序(merge_asof要求) sorted_df = df.sort_values("DateTime") # 匹配基准时间戳附近(7s内)的最近数据 matched_df = pd.merge_asof( base_df, sorted_df, on="DateTime", tolerance=pd.Timedelta("7s"), direction="nearest" ) merged_results.append(matched_df.drop(columns="DateTime")) # 3. 合并所有匹配结果 final_df = pd.concat(merged_results, axis=1)
方法2:双向merge_asof结合reduce(高效保留多源时间戳)
通过双向merge_asof(正向+反向)保留每次合并双方的时间戳,再用reduce批量合并:
from functools import reduce import pandas as pd def bidirectional_merge(left, right): # 正向合并:保留left时间戳,匹配right的最近数据 forward_merge = pd.merge_asof( left.sort_values("DateTime"), right.sort_values("DateTime"), on="DateTime", tolerance=pd.Timedelta("7s") ) # 反向合并:保留right时间戳,匹配left的最近数据 backward_merge = pd.merge_asof( right.sort_values("DateTime"), left.sort_values("DateTime"), on="DateTime", tolerance=pd.Timedelta("7s") ) # 合并两个结果并去重排序 combined = pd.concat([forward_merge, backward_merge]).drop_duplicates(subset="DateTime").sort_values("DateTime") return combined # 批量合并所有DataFrame final_df = reduce(bidirectional_merge, df_list)
注意事项
pd.merge_asof要求参与合并的DataFrame必须按on列排序,务必在合并前执行sort_values("DateTime")direction="nearest"会匹配容忍范围内的最近时间戳,比默认的backward更适配多偏移场景- 方法1能保留所有可能的有效时间戳,数据丢失最少;方法2更适合对内存占用有要求的场景
内容的提问来源于stack exchange,提问作者Janzaib M Baloch
相关产品推荐
相关产品推荐

