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

Pandas扩展DataFrame计算占比:优化低效循环实现方案需求

Pandas高效计算分组占比优化方案

问题说明

现有两个DataFrame:

源数据(df_source)

LocationTotal ValuesTotal Values 2
Location 1100300
Location 2200400

占比规则(df_fractions)

IdentFraction
Frac A0.25
Frac B0.75

需要生成新的DataFrame,将每个Location与所有占比标识组合,计算对应数值,目标结构如下:

LocationTotal ValuesTotal Values 2
Location 1 A2575
Location 1 B75225
Location 2 A50100
Location 2 B150300

当前使用逐行循环的方式实现,代码如下,但数据量大时效率极低:

ccalculated = []
for _, row in df_source.iterrows():
   for ident in df_fractions:
      new_row = row.copy()
      scaling_factor = df_fractions[df_fractions.loc[:, "Ident"] == "Frac A"]
      for values in ValueCols: 
         new_row[values] = np.multiply(new_row["Total Values"], scaling_factor)
     calculated.append(new_row)

优化方案:用Pandas向量化操作替代循环

Pandas的核心优势是向量化运算,避免逐行循环能大幅提升效率,具体步骤如下:

步骤1:生成Location与占比规则的全组合(交叉连接)

通过添加临时键实现两个DataFrame的笛卡尔积,得到所有Location和Ident的组合:

# 添加临时键用于交叉连接
df_source['tmp_key'] = 1
df_fractions['tmp_key'] = 1

# 交叉连接得到所有组合
merged_df = df_source.merge(df_fractions, on='tmp_key').drop('tmp_key', axis=1)

步骤2:计算各数值列的占比结果

直接对数值列做向量化乘法,避免逐元素循环:

# 计算占比后的值
merged_df['Total Values'] = merged_df['Total Values'] * merged_df['Fraction']
merged_df['Total Values 2'] = merged_df['Total Values 2'] * merged_df['Fraction']

步骤3:整理Location列并清理冗余列

把原Location和Ident拼接成新的Location名称,然后删除不需要的列:

# 拼接Location和Ident(提取Ident中的字母部分)
merged_df['Location'] = merged_df['Location'] + ' ' + merged_df['Ident'].str.replace('Frac ', '')

# 删除冗余列
result_df = merged_df.drop(['Ident', 'Fraction'], axis=1)

完整代码

import pandas as pd

# 示例数据初始化
df_source = pd.DataFrame({
    'Location': ['Location 1', 'Location 2'],
    'Total Values': [100, 200],
    'Total Values 2': [300, 400]
})

df_fractions = pd.DataFrame({
    'Ident': ['Frac A', 'Frac B'],
    'Fraction': [0.25, 0.75]
})

# 交叉连接生成全组合
df_source['tmp_key'] = 1
df_fractions['tmp_key'] = 1
merged_df = df_source.merge(df_fractions, on='tmp_key').drop('tmp_key', axis=1)

# 批量计算占比数值
merged_df[['Total Values', 'Total Values 2']] *= merged_df['Fraction'].values[:, None]

# 整理Location列格式
merged_df['Location'] = merged_df['Location'] + ' ' + merged_df['Ident'].str[-1]

# 清理冗余列并重置索引
result_df = merged_df.drop(['Ident', 'Fraction'], axis=1).reset_index(drop=True)

print(result_df)

运行后输出的result_df就是目标结构,且完全基于向量化操作,数据量越大,效率提升越明显。

效率提升原因

  • 避免了iterrows()逐行循环的Python层面开销,Pandas向量化操作基于底层C实现,速度远快于原生循环
  • 交叉连接和列运算均为批量处理,减少了内存拷贝和循环迭代的损耗

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.21 23:30:02