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

如何对依赖两个DataFrame的pandas自定义计算操作实现向量化优化

报错原因

你设置raw=True后,apply传入lambda的参数x是numpy数组而非pandas Series,不支持字符串索引(比如x['Cat']),只能用位置下标取值,这是触发IndexError的直接原因。如果一定要用raw=True,可以把代码里的x['Cat']改成x[0](对应df2第一列是Cat的情况),但这不会带来本质的性能提升,因为逐行遍历+每次布尔索引过滤df1的逻辑没有变。

优化方案

你不需要基于df2逐行遍历,完全可以通过优化计算函数+原生pandas分组操作实现十倍甚至百倍的性能提升:

1. 重构计算逻辑,移除无必要的pandas操作

原some_calc里的设置索引、DataFrame封装都是不必要的,你需要的外积矩阵完全可以用numpy实现,避免pandas的额外开销:

import pandas as pd
import numpy as np

def calc_per_cat_group(group):
    # 直接从分组片段中取数值转为numpy数组,运算速度远快于pandas接口
    data1 = group['data_point1'].values
    data2_sqrt = np.sqrt(group['data_point2'].values)
    # 转为列向量后做矩阵乘法直接得到M*M外积,不需要依赖索引保持维度
    vec = (data1 * data2_sqrt).reshape(-1, 1)
    grid = np.random.rand(vec.shape[0], vec.shape[0])
    # 直接用numpy逐元素乘+求和,没有额外开销
    return (vec @ vec.T * grid).sum()

2. 直接对df1做分组计算,避免逐行过滤

你本身就是按Cat分组计算,直接用pandas原生的groupby即可,内部是优化过的分组逻辑,远快于自己写布尔索引逐行过滤:

# 直接对df1按Cat分组计算,结果的索引为Cat分类值
group_calc_result = df1.groupby('Cat').apply(calc_per_cat_group).rename('Apply')
# 把计算结果合并到df2中,自动按Cat匹配
df2 = df2.merge(group_calc_result, on='Cat')

3. 可选:进一步极限优化

如果Cat分类数量很少(比如你示例里只有4类),还可以预先把所有组的片段存到字典里,完全避免pandas groupby的微小开销,不过一般场景下上面的方案已经足够满足性能需求。

原写法兼容方案(不推荐)

如果你不想修改原有some_calc的实现,也可以把raw=True版本的代码改为位置索引即可运行:

# 注意x[0]对应df2的第一列Cat,如果你的df2列顺序变化需要调整下标
df2['ApplyRaw'] = df2.apply(lambda x: some_calc(x=df1[df1['Cat']==x[0]][['Cat','data_point1']], 
                                                y=df1[df1['Cat']==x[0]][['Cat','data_point2']]),axis=1, raw=True)

这个写法只是解决了报错问题,性能没有任何提升,sample_size增大后仍然会很慢。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.25 19:06:03