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

在多级索引DataFrame中使用向量操作列并添加新列的优化方案咨询

在多级索引DataFrame中使用向量操作列并添加新列的优化方案咨询

你好,针对你提出的需求,完全可以用pandas的向量化操作替代循环,实现更简洁高效的处理,不需要手动创建空DataFrame再循环赋值。下面是具体的优化方案:

场景回顾

你有两个DataFrame:

  • df1:日期索引,列是二级多级索引,Level 0为Capitals(包含A、B、C),Level 1为Smalls(包含a、b、c、d、e),结构如下:
CapitalsABC
Smallsabcdeabcdeabcde
Date
01-01-25
01-02-25
01-03-25
01-04-25
  • df2:和df1相同的日期索引,包含X、Y、Z三列,结构如下:
XYZ
Date
01-01-25
01-02-25
01-03-25
01-04-25

你的需求是:

  1. 将df1中Capitals为B的所有Smalls列(Ba、Bb、Bc、Bd、Be)分别与df2的Z列相乘
  2. 将这5个结果列作为新的Capitals列D(对应Smalls的a、b、c、d、e)添加到df1中,最终得到如下结构:
CapitalsABCD
Smallsabcdeabcdeabcdeabcde
Date
01-01-25
01-02-25
01-03-25
01-04-25

优化后的向量式方案

你当前使用的循环方法虽然可行,但pandas的向量化操作可以大幅简化代码,同时提升运行效率(尤其是数据量较大时)。具体代码如下:

# 提取df1中Capitals为B的所有列,与df2的Z列进行广播相乘
d_group = df1['B'] * df2['Z'].values[:, None]

# 为结果设置多级列索引,保持和原df1一致的列名结构(Capitals='D',Smalls复用原有的a/b/c/d/e)
d_group.columns = pd.MultiIndex.from_product(
    [['D'], d_group.columns],
    names=df1.columns.names
)

# 将新的D组合并到原df1中
df1 = pd.concat([df1, d_group], axis=1)

代码解释:

  1. 提取并相乘:df1['B']直接获取二级索引中Capitals为B的所有列,df2['Z'].values[:, None]将Z列转换为二维数组,实现和B组的每一列进行广播相乘(自动对齐行索引),这一步完全是向量化操作,没有循环。
  2. 设置多级索引:用from_product快速生成新的多级列索引,确保和原df1的列结构一致,避免后续合并出现索引不匹配的问题。
  3. 合并DataFrame:用pd.concat将新生成的D组合并到原df1,完成添加。

如果你的需求是除法(看你代码里写的是/ df2['Z']),只需要把乘法改成除法即可:

d_group = df1['B'] / df2['Z'].values[:, None]

对比原方案的优势

  • 代码更简洁:去掉了创建空DataFrame、循环赋值的步骤,只用3行核心代码完成需求
  • 效率更高:向量化操作是pandas底层优化的C语言实现,比Python循环快得多,数据量越大优势越明显
  • 可读性更强:代码逻辑清晰,直接体现“提取B组→计算→合并”的流程

你当前的实现方法(供参考)

你原来的代码如下:

# Extract level 1 tickers from df1.columns
smalls = df1.columns.get_level_values(1).unique()

# Create new MultiIndex for the empty columns
new_columns = pd.MultiIndex.from_product(['D', smalls],names=df1.columns.names)

# Create an empty DataFrame with the new columns
empty_df = pd.DataFrame(0, index=df1.index, columns=new_columns)

# Concatenate with the original DataFrame
df1 = pd.concat([df1, empty_df], axis=1)

# Multiply dfs and populate D
for small in smalls:
    df1[('D', small)] = df1[('B', small)] / df2['Z']

备注:内容来源于stack exchange,提问作者AndysPythonStuff

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.13 19:45:32