基于时间区间合并Pandas DataFrames:为周数据添加关联月平均列
解决方法:匹配周数据与对应月份的平均值
要实现给周数据df_1添加对应月份的平均列,核心思路是让两个DataFrame基于「年份-月份」建立关联,然后将月平均值映射到每一行周数据上。下面给出两种高效的实现方式,适配你提到的多年完整数据场景:
方法一:用Pandas Merge(直观清晰)
这种方法通过提取统一的「年月周期」作为连接键,将月平均值合并到周数据中,逻辑一目了然,适合新手理解:
import pandas as pd # 第一步:确保日期列为datetime类型(如果你的原始数据还没转换的话) df_1['date'] = pd.to_datetime(df_1['date']) df_2['date'] = pd.to_datetime(df_2['date']) # 第二步:为两个DataFrame添加「年月周期」列(统一关联键) df_1['year_month'] = df_1['date'].dt.to_period('M') df_2['year_month'] = df_2['date'].dt.to_period('M') # 第三步:重命名df_2的列,避免和df_1的列冲突 df_2_renamed = df_2.rename(columns={ 'Direct_Connection': 'Assoc_dir_avg', 'Indirect_Connection': 'Ass_indir_avg' }) # 第四步:基于year_month合并,只保留需要的平均值列 merged_df = pd.merge( df_1, df_2_renamed[['year_month', 'Assoc_dir_avg', 'Ass_indir_avg']], on='year_month', how='left' # 保留df_1的所有行,即使没有对应月份的平均值 ) # 整理最终输出的列顺序,移除中间的year_month列 final_df = merged_df[['date', 'Direct_Connection', 'Assoc_dir_avg', 'Indirect_Connection', 'Ass_indir_avg']]
方法二:用字典映射(性能更优)
如果你的数据量很大(多年完整数据),这种方法的执行效率会更高,因为它直接通过字典做映射,避免了merge的额外开销:
import pandas as pd # 第一步:转换日期类型 df_1['date'] = pd.to_datetime(df_1['date']) df_2['date'] = pd.to_datetime(df_2['date']) # 第二步:将df_2转换成「年月周期: 平均值」的字典 month_avg_map = df_2.set_index(df_2['date'].dt.to_period('M'))[[ 'Direct_Connection', 'Indirect_Connection' ]].to_dict('index') # 第三步:直接给df_1添加平均值列 df_1['Assoc_dir_avg'] = df_1['date'].dt.to_period('M').map( lambda x: month_avg_map[x]['Direct_Connection'] ) df_1['Ass_indir_avg'] = df_1['date'].dt.to_period('M').map( lambda x: month_avg_map[x]['Indirect_Connection'] ) # 整理列顺序 final_df = df_1[['date', 'Direct_Connection', 'Assoc_dir_avg', 'Indirect_Connection', 'Ass_indir_avg']]
关键细节说明
dt.to_period('M'):这个方法会把日期转换成「YYYY-MM」格式的周期对象,不管是周中日期还是月末日期,同一个月份的周期值完全一致,是最可靠的关联方式。- 缺失值处理:如果
df_1中存在某个月份在df_2里没有对应平均值,两种方法都会在对应列生成NaN,你可以根据需求用fillna()填充或者dropna()删除这些行。 - 列名一致性:重命名
df_2的列是为了避免合并后出现重复列名,确保最终输出的列名和你期望的一致。
运行任意一种方法后,你都会得到和示例完全一致的输出结果。
内容的提问来源于stack exchange,提问作者moe_95
相关产品推荐
相关产品推荐

