You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Pandas中按日期列连接同/不同频率的DataFrame?

在Pandas中按日期列连接相同/不同频率的DataFrame

嘿,我来帮你解决Pandas里按日期连接不同DataFrame的问题,咱们针对你给出的三个场景逐一拆解,每个场景都附上可直接运行的代码和思路说明:

场景1:同频率(月度)但日期不全匹配的左连接

这个场景里两个DataFrame都是月度日期,只是slow的日期更少,咱们直接用pd.merge按date列做左连接就行,分别以fast和slow为基准:

import pandas as pd

# 初始化数据
fast = pd.DataFrame({ 
    'date': pd.to_datetime(['2018-01', '2018-02', '2018-03', '2018-04', '2018-05', '2018-06']), 
    'store': ['A'] * 3 + ['B'] * 3, 
    'sales': [3000, 2000, 1800, 1700, 1500, 1600]
}) 
slow = pd.DataFrame({ 
    'date': pd.to_datetime(['2018-01', '2018-03', '2018-06']), 
    'temp': [45, 55, 70]
})

# 以fast为基准的左连接
alligned_left_fast = pd.merge(fast, slow, on='date', how='left')
# 以slow为基准的左连接
alligned_left_slow = pd.merge(slow, fast, on='date', how='left')

思路说明:因为两个DataFrame的日期频率完全一致(都是月度),直接通过on='date'指定连接键,how='left'保留基准DataFrame的所有行,匹配不到的列会填充NaN。

场景2:同频率但日期点不对齐的左连接

这里注意你给出的unaligned_df2代码有小问题,我先修正了(pd.to_datetime不能直接传periods参数,改用pd.date_range)。这个场景是同频率但日期不是完全重合的点,咱们用pd.merge_asof做近似日期匹配:

import pandas as pd

# 初始化数据
unaligned_df1 = pd.DataFrame({ 
    'date': pd.to_datetime(['2018-01', '2018-02', '2018-03', '2018-04', '2018-05', '2018-06']), 
    'store': ['A'] * 3 + ['B'] * 3, 
    'sales': [3000, 2000, 1800, 1700, 1500, 1600]
}) 
# 修正后的unaligned_df2创建代码
unaligned_df2 = pd.DataFrame({ 
    'date': pd.date_range('2018-02-11', periods=6, freq='30D'), 
    'temp': [105, 95, 87, 78, 66, 55]  # 补全对应6个日期的temp值
})

# merge_asof要求两个DataFrame按连接键排序
df1_sorted = unaligned_df1.sort_values('date')
df2_sorted = unaligned_df2.sort_values('date')

# 左连接,以df1的日期为基准,匹配最近的不大于当前日期的df2日期
Unaligned_merged_left_date_index = pd.merge_asof(df1_sorted, df2_sorted, on='date', direction='backward')

思路说明:merge_asof专门用于时间序列的近似匹配,适合同频率但日期点不对齐的场景。direction='backward'表示为每个df1的日期找最近的、不晚于它的df2日期,你也可以根据需求换成forward(找不早于的)或nearest(找最近的)。

场景3:不同频率(日度vs月度)的连接

这个场景里一个是日度数据,一个是月度数据,咱们需要先把高频的日度日期对齐到月度频率,再做连接:

import pandas as pd

# 初始化数据
unaligned_fast_diff_freq = pd.DataFrame({ 
    'date': pd.to_datetime(['2018-01-12', '2018-02-10', '2018-02-16', '2018-04-28', '2018-04-29', '2018-06-11']), 
    'store': ['A'] * 3 + ['B'] * 3, 
    'sales': [3000, 2000, 1800, 1700, 1500, 1600]
}) 
unaligned_slow_diff_freq = pd.DataFrame({ 
    'date': pd.to_datetime(['2018-04', '2018-05', '2018-01', '2018-06']), 
    'sales_monthly': [2700, 2500, 2600, 3300]  # 重命名列避免冲突
})

# 把日度日期转成月度周期,月度日期也统一转成相同格式
unaligned_fast_diff_freq['month'] = unaligned_fast_diff_freq['date'].dt.to_period('M')
unaligned_slow_diff_freq['month'] = unaligned_slow_diff_freq['date'].dt.to_period('M')

# 按月度周期连接,之后删除临时列
unaligned_fast_slow = pd.merge(unaligned_fast_diff_freq, unaligned_slow_diff_freq, on='month', how='left').drop('month', axis=1)

思路说明:不同频率的日期无法直接匹配,所以我们把日度数据向下采样到月度(用dt.to_period('M')生成月度周期对象),和月度数据的日期统一格式后,再用常规的merge连接。如果不想新增临时列,也可以用dt.floor('M')把日期对齐到当月第一天,直接作为连接键。


内容的提问来源于stack exchange,提问作者coder

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 06:26:20