如何在Pandas中基于另一数据框的条件为目标数据框添加均值列
解决方案:为DataFrame1添加指定范围的均值列
这里有几种高效的方法能帮你实现需求,我一步步拆解最直观好维护的方案:
方法一:用merge+groupby实现向量化计算(适合大数据集)
这种方法利用Pandas的向量化操作,效率更高,适合处理大规模数据:
import pandas as pd # 先构造示例数据(和你给出的结构一致) df1 = pd.DataFrame({ 'country': [1, 2], 'type': ['a', 'b'], 'start_week': [12, 13], 'end_week': [13, 14] }) df2 = pd.DataFrame({ 'country': [1,1,1,2,2,2], 'type': ['a','a','a','b','b','b'], 'week': [12,13,14,12,13,14], 'value': [1000,900,800,1000,900,800] }) # 1. 按country+type合并两个DataFrame,保留df1的所有行 merged_df = pd.merge(df1, df2, on=['country', 'type'], how='left') # 2. 筛选出week在start_week到end_week之间的记录 filtered_df = merged_df[(merged_df['week'] >= merged_df['start_week']) & (merged_df['week'] <= merged_df['end_week'])] # 3. 按df1的行维度分组,计算value的均值 avg_result = filtered_df.groupby(['country', 'type', 'start_week', 'end_week'])['value'].mean().reset_index(name='avg') print(avg_result)
运行后会得到你想要的输出:
country type start_week end_week avg 0 1 a 12 13 950.0 1 2 b 13 14 850.0
方法二:用apply逐行计算(适合小数据集)
如果你的数据量不大,这种方法逻辑更直观,调试起来也方便:
import pandas as pd # 同样先构造示例数据 df1 = pd.DataFrame({ 'country': [1, 2], 'type': ['a', 'b'], 'start_week': [12, 13], 'end_week': [13, 14] }) df2 = pd.DataFrame({ 'country': [1,1,1,2,2,2], 'type': ['a','a','a','b','b','b'], 'week': [12,13,14,12,13,14], 'value': [1000,900,800,1000,900,800] }) # 定义一个函数,逐行计算对应范围的均值 def get_group_avg(row): # 筛选符合条件的记录 match_mask = (df2['country'] == row['country']) & \ (df2['type'] == row['type']) & \ (df2['week'] >= row['start_week']) & \ (df2['week'] <= row['end_week']) return df2[match_mask]['value'].mean() # 给df1添加avg列 df1['avg'] = df1.apply(get_group_avg, axis=1) print(df1)
关键提示
- 两种方法的核心都是匹配country+type分组和筛选week的范围这两个条件;
- 方法一的向量化操作效率远高于方法二的逐行处理,优先推荐用于大数据场景;
- 如果你的数据里存在
country+type组合在df2中没有对应记录的情况,两种方法都会返回NaN,可以根据需求用fillna()处理。
内容的提问来源于stack exchange,提问作者Lombrosso
相关产品推荐
相关产品推荐

