如何按组高效实现Pandas DataFrame对应元素乘法?
问题描述
我有一个包含group列和特征列(feature 1、feature 2)的pandas DataFrame:
| group | feature 1 | feature 2 |
|---|---|---|
| A | 1 | 1 |
| A | 2 | 1 |
| B | 1 | 1 |
| B | 2 | 1 |
另有一个乘数表,包含每个group对应各feature的乘数:
| group | feature 1 | feature 2 |
|---|---|---|
| A | 1 | 2 |
| B | 3 | 4 |
我将第一个表定义为data,第二个表定义为multiplier,尝试了以下代码:
data2 = data.copy() for i in range(len(multipliers)): mul = multipliers[features].loc[i] all_data2.loc[all_data2.group==i,features] = all_data2.loc[all_data2.group==0,features]*mul
预期得到的结果为:
| group | feature 1 | feature 2 |
|---|---|---|
| A | 1 | 2 |
| A | 2 | 2 |
| B | 3 | 4 |
| B | 6 | 4 |
(每个group的对应feature与乘数相乘)
该代码可正常运行,但处理大数据集时速度极慢,请问有什么更高效的实现方式?
高效实现方案
方法1:广播乘法(最优性能)
利用pandas的索引匹配和广播机制,直接对整列执行向量化乘法,完全避免循环:
# 将乘数表设置为group为索引,然后根据data的group列匹配对应的乘数 multiplier_indexed = multiplier.set_index('group') matched_muls = multiplier_indexed.reindex(data['group']).reset_index(drop=True) # 执行广播乘法,直接更新特征列 data2 = data.copy() data2[['feature 1', 'feature 2']] = data[['feature 1', 'feature 2']] * matched_muls
方法2:合并后逐列计算
通过合并两个表,明确关联每个行的乘数后再执行乘法,逻辑更直观:
# 给乘数表的列添加后缀,避免合并后列名冲突 multiplier_renamed = multiplier.add_suffix('_mul').rename(columns={'group_mul': 'group'}) # 按group列合并两个表 merged = data.merge(multiplier_renamed, on='group') # 对每个特征列执行原数值×对应乘数的操作 for feat in ['feature 1', 'feature 2']: merged[feat] = merged[feat] * merged[f'{feat}_mul'] # 提取最终需要的列 data2 = merged[['group', 'feature 1', 'feature 2']]
方法3:分组映射乘法
借助groupby分组后,对每组应用对应group的乘数:
# 将乘数表转为字典,key为group,value为对应特征的乘数字典 mul_dict = multiplier.set_index('group').to_dict('index') # 分组后对每组的特征列执行乘法 data2 = data.copy() data2[['feature 1', 'feature 2']] = data2.groupby('group', group_keys=False).apply( lambda x: x[['feature 1', 'feature 2']] * mul_dict[x.name] )
以上三种方法均采用pandas内置的向量化操作,避免了原生Python循环的性能损耗,在大数据集场景下速度会有显著提升,其中方法1的代码最简洁,性能最优。
内容的提问来源于stack exchange,提问作者Lucas Morin
相关产品推荐
相关产品推荐

