如何高效计算两个Pandas DataFrame的加权平均值(仅单元格均存在时)
高效实现DataFrame子集加权平均的方法
嘿,这个问题我太熟了!嵌套循环加异常捕获在小数据集上凑合用,但碰到大表真的会慢到让人抓狂。用pandas的原生矢量化操作就能完美解决,效率直接拉满~
核心思路
我们只需要针对df1和df2共有的索引、列位置计算加权平均(df2权重0.4,df1权重0.6),其余位置保留df1原值。关键是用pandas的内置方法替代Python循环,充分利用底层C实现的矢量化运算优势。
具体实现方法
这里提供两种简洁高效的方案,任选其一即可:
方法1:重索引 + 填充
先将df2对齐到df1的索引和列结构(缺失位置自动填充NaN),再计算加权值,最后把NaN位置替换回df1的原值:
import pandas as pd # 初始化你的DataFrame df1 = pd.DataFrame({"a": [0.5,0.5,0.5], "b": [0.5,0.5,0.5], "c": [0.5,0.5,0.5]}, index = ["a", "b", "c"]) df2 = pd.DataFrame({"a": [0.3,0.3], "b": [0.3,0.3]}, index = ["a", "b"]) # 对齐df2到df1的结构 df2_aligned = df2.reindex_like(df1) # 计算加权值(df2存在的位置正常计算,不存在的位置为NaN) weighted_values = df2_aligned * 0.4 + df1 * 0.6 # 填充NaN为df1的原值 final_result = weighted_values.fillna(df1)
方法2:掩码 + where条件
先标记出df2存在的位置,再用where方法在对应位置替换为加权值,其余位置保留df1:
import pandas as pd df1 = pd.DataFrame({"a": [0.5,0.5,0.5], "b": [0.5,0.5,0.5], "c": [0.5,0.5,0.5]}, index = ["a", "b", "c"]) df2 = pd.DataFrame({"a": [0.3,0.3], "b": [0.3,0.3]}, index = ["a", "b"]) # 生成掩码:标记df2存在的位置(True表示有值,False表示无) mask = df2.reindex_like(df1).notna() # 应用条件:掩码为True的位置用加权值,否则保留df1原值 final_result = df1.where(~mask, df2*0.4 + df1*0.6)
结果验证
两种方法都会得到相同的输出:
a b c a 0.42 0.42 0.5 b 0.42 0.42 0.5 c 0.50 0.50 0.5
其中共有的行列位置(a/a、a/b、b/a、b/b)计算了0.3*0.4 + 0.5*0.6 = 0.42,其余位置保留了df1的0.5原值。
为什么更高效
这两种方案都完全依赖pandas的矢量化操作,底层是C语言实现的,避免了Python层面的循环开销。在处理大型DataFrame时,速度会比嵌套循环快几个数量级,同时代码更简洁易维护。
内容的提问来源于stack exchange,提问作者Julian
相关产品推荐
相关产品推荐

