如何基于另一DataFrame的时间区间条件为当前DataFrame匹配取值
Pandas 时间区间匹配实现方案
核心逻辑是先将字符串格式的时间统一转为datetime类型,再按照区间规则关联两个DataFrame,优先推荐性能更高的merge_asof方案:
完整实现代码
import pandas as pd # 初始化原始数据 df1 = pd.DataFrame([1,2,3], index=['2020-12-31 23:00:00','2021-01-01 00:00:00','2021-01-01 01:00:00'], columns=['origin_val']) df2 = pd.DataFrame([['2020-01-01 00:00:00','2021-01-01 00:00:00',70], ['2021-01-01 00:00:00','2022-01-01 00:00:00',65]], columns=['From','To','Value']) # 统一转换为datetime类型,避免字符串比较出现异常 df1.index = pd.to_datetime(df1.index) df2[['From', 'To']] = df2[['From', 'To']].apply(pd.to_datetime) # 用merge_asof实现区间匹配(大数据量优先选择,性能远高于逐行遍历) result = pd.merge_asof( left=df1.reset_index(), right=df2.sort_values('From'), # merge_asof要求右表匹配键为升序 left_on='index', right_on='From', direction='backward' ) # 补充筛选小于To的条件,匹配业务规则 result = result[result['index'] < result['To']] # 还原索引,保留目标列 result = result.set_index('index')[['origin_val', 'Value']]
执行后得到的result就是你需要的目标DataFrame,索引与原df1完全一致,两列分别为原df1的数值和匹配到的Value。
小数据量简化方案
如果数据量很小,可以用更直观的逐行匹配写法:
def match_value(dt): filter_df = df2[(df2['From'] <= dt) & (df2['To'] > dt)] return filter_df['Value'].iloc[0] if not filter_df.empty else pd.NA df1['Value'] = df1.index.map(match_value)
内容的提问来源于stack exchange,提问作者PYTHON
相关产品推荐
相关产品推荐

