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

如何实现两个DataFrame匹配列行相乘后按行求和生成新DataFrame?

问题需求

我有两个Pandas DataFrame:

import pandas as pd

df1 = pd.DataFrame( {'spot': [1,2,3], 'ID1': [0,1,0], 'ID2': [1, 1, 2], 'ID3': [0,0,1]})
df2 = pd.DataFrame( {'ID': ['ID1','ID2','ID3'], 'prop1': [0.01,0.8,0.0], 'prop2': [0.0, 0.04, 0.5]})

df1输出:

spot  ID1  ID2  ID3
0     1    0    1    0
1     2    1    1    0
2     3    0    2    1

df2输出:

ID  prop1  prop2
0  ID1   0.01   0.00
1  ID2   0.80   0.04
2  ID3   0.00   0.50

中间预期效果(仅作示意):

spot        ID1                ID2             ID3
0     1         0           [1*0.8, 1*0.04]        0
1     2   [1*0.01, 1*0.0]   [1*0.8, 1*0.04]        0
2     3         0           [2*0.8, 2*0.04]  [1*0.0, 1*0.5]

最终希望生成包含spot、prop1、prop2的DataFrame,其中每行的prop1为所有ID列对应prop1乘积之和,prop2同理:

spot  prop1            prop2 
0     1 (1*0.8)          (1*0.04)    
1     2 (1*0.01 + 1*0.8) (1*0.04)    
2     3 (2*0.8 + 0)      (2*0.04 + 1*0.5)

尝试的代码(未得到预期结果):

arr = df1.iloc[:, 1:].to_numpy()
arr2 = df2.iloc[:, 1:].to_numpy()

for i in range(len(arr)):
    for j in range(len(arr)):
        print(arr[i, j] * arr2[i])
解决方案

不需要嵌套循环,直接利用Pandas的广播和矩阵运算就能高效实现:

核心实现(直接得到数值结果)

# 提取df1的ID数值部分,以spot为索引
df1_ids = df1.set_index('spot')
# 提取df2的prop数值部分,以ID为索引后转置,让prop类型成为行、ID成为列
df2_props = df2.set_index('ID').T

# 矩阵乘法:自动完成每行ID值与对应prop的乘积求和
result = df1_ids @ df2_props

# 合并spot列并重置索引
final_df = result.reset_index()

print(final_df)

输出结果:

spot  prop1  prop2
0     1   0.80   0.04
1     2   0.81   0.04
2     3   1.60   0.58

带计算过程的示意输出

如果需要像需求里那样显示求和表达式,可以额外生成字符串列:

prop1_expr = []
prop2_expr = []

for _, row in df1.iterrows():
    p1_parts = []
    p2_parts = []
    # 遍历每个ID列,收集非零值的计算项
    for col in ['ID1', 'ID2', 'ID3']:
        val = row[col]
        if val == 0:
            continue
        # 匹配df2中对应ID的prop值
        p1 = df2.loc[df2['ID'] == col, 'prop1'].values[0]
        p2 = df2.loc[df2['ID'] == col, 'prop2'].values[0]
        p1_parts.append(f"{val}*{p1}")
        p2_parts.append(f"{val}*{p2}")
    # 拼接成表达式字符串
    prop1_expr.append(f"({' + '.join(p1_parts)})" if p1_parts else "(0)")
    prop2_expr.append(f"({' + '.join(p2_parts)})" if p2_parts else "(0)")

# 添加到结果中
final_df['prop1_expr'] = prop1_expr
final_df['prop2_expr'] = prop2_expr

print(final_df[['spot', 'prop1_expr', 'prop2_expr']])

输出:

spot       prop1_expr       prop2_expr
0     1          (1*0.8)         (1*0.04)
1     2  (1*0.01 + 1*0.8)         (1*0.04)
2     3          (2*0.8)  (2*0.04 + 1*0.5)

原代码问题说明

原代码的嵌套循环索引逻辑错误:j遍历的是行数而非列数,且arr2[i]取的是df2的第i行,实际应该取df2的第j行(对应df1的第j个ID列);同时缺少对每行乘积的求和操作,导致无法得到目标结果。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.23 07:09:12