如何匹配两个DataFrame的时间区间,复制对应温湿度数据到DF1
原代码失效原因
iterrows()返回的行对象是DataFrame数据的副本,直接修改副本不会对原始DF1生效- 代码中的
row2 += 1属于冗余逻辑,iterrows()本身会自动遍历DF2的所有行,该操作不会改变遍历进程 - 额外注意:你提供的DF2字段名存在笔误,
MgsTime2应为MsgTime2,运行代码前需先修正字段名,否则会报字段不存在错误
正确实现步骤
步骤1:统一转换时间字段格式
首先需要将所有时间字段转为pandas可识别的时间类型,避免直接用字符串比较出现逻辑错误:
import pandas as pd import numpy as np # 转换时间列为timedelta格式(适配纯时间场景,也可根据需求转为datetime格式) DF1['MsgTime'] = pd.to_timedelta(DF1['MsgTime']) DF2['MsgTime1'] = pd.to_timedelta(DF2['MsgTime1']) DF2['MsgTime2'] = pd.to_timedelta(DF2['MsgTime2']) # 初始化DF1的结果字段为NaN DF1['Temperature'] = np.nan DF1['Humidity'] = np.nan
步骤2:匹配取值
方案1:循环实现(逻辑和你原写法对齐,适合小数据量)
for idx, row in DF1.iterrows(): # 筛选DF2中符合时间区间的匹配行 match_df = DF2[(DF2['MsgTime1'] <= row['MsgTime']) & (DF2['MsgTime2'] >= row['MsgTime'])] if not match_df.empty: # 通过索引直接修改原始DF1的值 DF1.loc[idx, 'Temperature'] = match_df.iloc[0]['Temperature'] DF1.loc[idx, 'Humidity'] = match_df.iloc[0]['Humidity']
方案2:向量化实现(无循环,适合大数据量场景)
# 交叉连接后筛选匹配行,再合并回DF1 cross_df = DF1.assign(tmp_key=1).merge(DF2.assign(tmp_key=1), on='tmp_key').drop('tmp_key', axis=1) match_res = cross_df[(cross_df['MsgTime1'] <= cross_df['MsgTime']) & (cross_df['MsgTime2'] >= cross_df['MsgTime'])][['MsgTime', 'Temperature', 'Humidity']] DF1 = DF1[['MsgTime']].merge(match_res, on='MsgTime', how='left')
可选:时间格式还原
如果需要把输出的时间列还原为HH:MM:SS字符串格式,添加以下代码即可:
DF1['MsgTime'] = DF1['MsgTime'].astype(str).str[-8:]
处理完成后的DF1就是你需要的输出结果。
内容的提问来源于stack exchange,提问作者Jack Tan
相关产品推荐
相关产品推荐

