Pandas:合并不同采样率的DataFrame且避免值重复
合并不同采样率的Pandas DataFrame并避免重复值
看起来你想要的是仅在每个HR时间点对应的第一个Tobii记录上显示HR值,同时间段内的其他Tobii记录留空——而你当前用的merge_asof和reindex方法会自动向前填充/匹配最近值,导致同一时间段内的所有Tobii记录都重复显示同一个HR值,这正是问题所在。
问题根源
merge_asof默认采用**向后匹配(backward)**逻辑,会给每个Tobii记录找到最近的、早于它的HR时间点,然后把对应HR值填充给该时间段内的所有Tobii记录。reindex(method='nearest')则是给每个Tobii时间点匹配最近的HR时间点,同样会导致同时间段内的记录重复绑定同一个值。
解决方案
我们可以先通过merge_asof完成基础时间匹配,然后只保留每个HR时间段内第一条Tobii记录的HR值,其余记录设为空值(pd.NA)。具体步骤如下:
1. 确保时间列为datetime类型
首先要保证两个DataFrame的datetime列都是Pandas的datetime格式,否则时间匹配会出错:
import pandas as pd # 转换时间列类型(如果还未转换) tobii_df['datetime'] = pd.to_datetime(tobii_df['datetime']) hr_df['datetime'] = pd.to_datetime(hr_df['datetime'])
2. 基础匹配+去重处理
用merge_asof完成初始匹配,然后通过duplicated()标记重复的HR时间点对应的记录,只保留第一条的HR值:
# 先按时间排序(merge_asof要求输入是排序后的数据集) tobii_sorted = tobii_df.sort_values('datetime') hr_sorted = hr_df.sort_values('datetime') # 用merge_asof匹配每个Tobii记录对应的HR数据 merged = pd.merge_asof( tobii_sorted, hr_sorted, on='datetime', direction='backward' # 匹配最近的、早于当前Tobii时间的HR记录 ) # 仅保留每个HR时间点对应的第一条Tobii记录的col2值,其余设为空 merged['col2'] = merged['col2'].where(~merged['datetime_y'].duplicated(), pd.NA) # 整理最终结果,保留需要的列并重置索引 final_df = merged[['datetime', 'col1', 'col2']].reset_index(drop=True)
结果验证
运行后你会得到和期望一致的结果:
| datetime | col1 | col2 |
|---|---|---|
| 2017-08-24 12:59:00.753 | 1.3 | 60 |
| 2017-08-24 12:59:13.753 | 7.2 | |
| 2017-08-24 12:59:13.773 | 6.1 | |
| 2017-08-24 12:59:13.793 | 5.1 | |
| 2017-08-24 13:00:00.813 | 5.4 | 64 |
代码解释
merge_asof(..., direction='backward'):确保每个Tobii记录匹配到的是最近的、早于它的HR时间点,保证时间逻辑的正确性。merged['datetime_y'].duplicated():标记哪些Tobii记录对应的HR时间点是重复的(即不是该时间段的第一条记录)。where()方法:仅当duplicated()返回False时(也就是该HR时间段的第一条Tobii记录)保留col2值,否则设为pd.NA。
内容的提问来源于stack exchange,提问作者Mohamed Taher Alrefaie
相关产品推荐
相关产品推荐

