如何仅基于日和月合并DataFrame,匹配指定日期范围
这问题核心就是跨年份的月日匹配合并,用Pandas的日期处理功能就能轻松解决,我给你一步步拆解实现:
解决方案步骤
1. 先把日期列转为datetime类型
不管是df0还是df1,第一步必须把字符串格式的日期转成Pandas的datetime对象,这样才能方便提取月日信息。
import pandas as pd # 先构造你提供的示例数据(方便直接测试) df0 = pd.DataFrame({'date': ['12/30/2018', '12/31/2018', '1/1/2019', '1/2/2019', '1/3/2019']}) df1 = pd.DataFrame({ 'date': ['12/30/2017', '12/31/2017', '1/1/2017', '1/2/2017', '1/3/2017', '12/30/2017', '12/31/2017', '1/1/2017', '1/2/2017', '1/3/2017'], 'loc': ['YYC']*5 + ['YYZ']*5, 'temp': [5.07, 5.64, 3.43, 7.89, 2.49, 4.08, 7.40, 7.82, 8.33, 7.74] }) # 转换日期列格式 df0['date'] = pd.to_datetime(df0['date']) df1['date'] = pd.to_datetime(df1['date'])
2. 创建月日匹配键
接下来给两个DataFrame新增一个month_day列,存储统一格式的月-日字符串(比如12-30、01-01),这样就能完全忽略年份,只靠月日来匹配数据。
# 提取月日并统一格式为MM-DD,避免1月写成"1-1"这种不统一的情况 df0['month_day'] = df0['date'].dt.strftime('%m-%d') df1['month_day'] = df1['date'].dt.strftime('%m-%d')
3. 基于month_day合并数据
现在用pd.merge()做左连接,保留df0的所有日期行,匹配df1中相同月日的记录:
# 合并数据,suffixes用来区分两个df中重名的date列 merged_df = pd.merge(df0, df1, on='month_day', how='left', suffixes=('_target', '_source')) # 整理最终结果,保留需要的列 final_df = merged_df[['date_target', 'loc', 'temp']].rename(columns={'date_target': 'target_date'})
完整代码&运行结果
把上面的步骤整合起来,运行后得到的结果就是你想要的:
import pandas as pd # 构造示例DataFrame df0 = pd.DataFrame({'date': ['12/30/2018', '12/31/2018', '1/1/2019', '1/2/2019', '1/3/2019']}) df1 = pd.DataFrame({ 'date': ['12/30/2017', '12/31/2017', '1/1/2017', '1/2/2017', '1/3/2017', '12/30/2017', '12/31/2017', '1/1/2017', '1/2/2017', '1/3/2017'], 'loc': ['YYC']*5 + ['YYZ']*5, 'temp': [5.07, 5.64, 3.43, 7.89, 2.49, 4.08, 7.40, 7.82, 8.33, 7.74] }) # 转换日期格式 df0['date'] = pd.to_datetime(df0['date']) df1['date'] = pd.to_datetime(df1['date']) # 创建月日匹配键 df0['month_day'] = df0['date'].dt.strftime('%m-%d') df1['month_day'] = df1['date'].dt.strftime('%m-%d') # 合并数据 merged_df = pd.merge(df0, df1, on='month_day', how='left', suffixes=('_target', '_source')) # 整理最终结果 final_df = merged_df[['date_target', 'loc', 'temp']].rename(columns={'date_target': 'target_date'}) print(final_df)
输出结果:
target_date loc temp 0 2018-12-30 YYC 5.07 1 2018-12-30 YYZ 4.08 2 2018-12-31 YYC 5.64 3 2018-12-31 YYZ 7.40 4 2019-01-01 YYC 3.43 5 2019-01-01 YYZ 7.82 6 2019-01-02 YYC 7.89 7 2019-01-02 YYZ 8.33 8 2019-01-03 YYC 2.49 9 2019-01-03 YYZ 7.74
额外注意点
- 如果
df0里有闰年的2月29日,而df1没有对应数据,合并后会出现NaN,你可以根据需求用fillna()处理。 - 要是怕
strftime的格式问题,也可以用dayofyear作为匹配键,但要注意闰年的dayofyear会比平年多1天,需要额外兼容。
内容的提问来源于stack exchange,提问作者thesimplevoodoo
相关产品推荐
相关产品推荐

