Pandas使用merge_asof合并DataFrame出现重复行问题求解
问题原因
你的推测是正确的,出现行数膨胀的核心原因是两个DataFrame同秒内都有10条数据,仅靠时间列合并时,左表每条毫秒级时间的行,会匹配到右表同秒的全部10条整秒时间的行,最终产生10倍于原始数据的重复行。
另外你当前使用的merge_asof逻辑也不符合要求:merge_asof要求右表的on字段(也就是TIME列)是严格单调递增的,而你的右表(整秒时间的DataFrame)TIME列每秒有10个重复值,不满足merge_asof的使用前提,会导致匹配逻辑异常。
解决方案
因为两个DataFrame都是10Hz采集,每秒固定有10条数据,最优方案是给同秒内的行加顺序编号,按「秒级时间+顺序编号」双字段做一一对应合并,代码示例如下:
import pandas as pd # 第一步:统一两个DataFrame的TIME列类型为datetime(如果还未做类型转换) df_ms['TIME'] = pd.to_datetime(df_ms['TIME']) # 带毫秒的DataFrame,对应你的ewholedf df_sec['TIME'] = pd.to_datetime(df_sec['TIME']) # 整秒的DataFrame,对应你的wholedf # 第二步:给两个DataFrame新增秒级时间列、同秒内顺序号列 df_ms = df_ms.assign( time_sec = df_ms['TIME'].dt.floor('S'), # 时间截断到秒 seq = df_ms.groupby('time_sec').cumcount() # 同秒内从0开始的顺序编号 ) df_sec = df_sec.assign( time_sec = df_sec['TIME'].dt.floor('S'), seq = df_sec.groupby('time_sec').cumcount() ) # 第三步:按time_sec和seq双字段合并,避免重复匹配 merged_df = pd.merge(df_ms, df_sec, on=['time_sec', 'seq'], suffixes=('_ms', '_sec')) # 第四步:清理辅助列,按需调整输出字段 merged_df = merged_df.drop(['time_sec', 'seq'], axis=1) # 可保留毫秒级时间作为主时间列 merged_df = merged_df.rename(columns={'TIME_ms': 'TIME'}) # 输出到CSV merged_df.to_csv('merged_result.csv', index=False)
补充说明
- 如果两个DataFrame的采集顺序存在偏移,不是完全同秒内1:1对齐,可以在合并后计算两个表原始TIME列的差值,过滤出差值超过50ms(10Hz采集间隔的一半)的异常匹配行,避免错位。
- 如果存在某秒数据丢失不足10条的情况,可以把merge的参数改成
how='outer',保留所有行后再按需补全空值。
内容的提问来源于stack exchange,提问作者Leopold Wahlbeck
相关产品推荐
相关产品推荐

