基于Pandas按主题分组计算两个DataFrame点积的高效方法
按Theme分组计算点积的高效方法
这是一个很常见的需求,我们可以利用Pandas的向量化操作来高效实现,避免手动循环带来的性能问题。下面是具体的步骤和代码:
步骤说明
- 先按
Theme对df1进行分组,获取每个主题对应的组件(Component)和对应的权重(Weights)。 - 对每个主题组,提取
df2中对应的组件列,与该组的权重进行点积运算(即逐行计算加权和)。 - 将所有主题的结果合并成一个新的DataFrame,每行对应
df2的一行,每列对应一个主题的计算结果。
完整代码
首先先确认你的数据(方便复现):
import pandas as pd df1 = pd.DataFrame( {'Component': ['A','B','C','D'], 'Theme': ['T1','T2','T3','T3'], 'Weights': [0.5,0.1,0.1,0.3]}, index=[0, 1, 2, 3] ) df2 = pd.DataFrame( {'A': [-0.1,0.05,-0.07,-0.5,0.02], 'B': [-0.3,0.02,-0.01,-0.4,0.01], 'C': [-0.8,0.00,-0.01,-0.1,0.07], 'D': [-0.08,0.1,-0.01,-0.05,0.03],}, index=[0, 1, 2, 3,4] )
然后执行核心计算:
# 按Theme分组df1 theme_groups = df1.groupby('Theme') # 遍历每个主题组,计算对应点积 theme_results = { theme: df2[group['Component']].dot(group['Weights']) for theme, group in theme_groups } # 转换为DataFrame,得到最终结果 result_df = pd.DataFrame(theme_results)
结果验证
比如我们手动计算T3主题的第一行结果:
- T3对应组件C(权重0.1)和D(权重0.3)
- df2第一行C的值是-0.8,D的值是-0.08
- 计算:
0.1*(-0.8) + 0.3*(-0.08) = -0.08 - 0.024 = -0.104
查看result_df的第一行T3列,确实是-0.104,说明计算正确。
为什么这个方法高效?
这里用到了Pandas的dot()方法,它是基于NumPy的向量化运算实现的,比手动遍历每一行计算要快得多,尤其是当df2的行数很多时,性能优势会非常明显。
如果你想要更简洁的写法,也可以用一行代码完成(本质和上面的逻辑一致):
result_df = pd.DataFrame({ t: df2[g['Component']].dot(g['Weights']) for t, g in df1.groupby('Theme') })
内容的提问来源于stack exchange,提问作者CTXR
相关产品推荐
相关产品推荐

