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

如何在双重MultiIndex的pd.DataFrame中高效实现A行与B行等值赋值?

高效修改MultiIndex DataFrame指定行值的方法

首先创建行列均为MultiIndex的DataFrame:

import pandas as pd
import numpy as np

columns = pd.MultiIndex.from_tuples([('a', 2), ('a', 3), ('b', 1), ('b', 3)], names=['col_1', 'col_2'])
index = pd.MultiIndex.from_tuples([(pd.Timestamp('2023-03-01'), 'A'), 
                                   (pd.Timestamp('2023-03-01'), 'B'), 
                                   (pd.Timestamp('2023-03-01'), 'C'), 
                                   (pd.Timestamp('2023-03-02'), 'A'), 
                                   (pd.Timestamp('2023-03-02'), 'B'), 
                                   (pd.Timestamp('2023-03-03'), 'B'), 
                                   (pd.Timestamp('2023-03-03'), 'C')], names=['idx_1', 'idx_2'])
data = np.arange(len(index) * len(columns)).reshape(len(index), len(columns))
df = pd.DataFrame(index=index, columns=columns, data=data)

生成的DataFrame如下:

col_1              a       b    
col_2              2   3   1   3
idx_1      idx_2                
2023-03-01 A       0   1   2   3
           B       4   5   6   7
           C       8   9  10  11
2023-03-02 A      12  13  14  15
           B      16  17  18  19
2023-03-03 B      20  21  22  23
           C      24  25  26  27

需求说明

将每个日期(idx_1)分组下的idx_2='A'行,替换为同组内idx_2='B'行的数值,预期结果如下:

col_1              a       b    
col_2              2   3   1   3
idx_1      idx_2                
2023-03-01 A       4   5   6   7
           B       4   5   6   7
           C       8   9  10  11
2023-03-02 A      16  17  18  19
           B      16  17  18  19
2023-03-03 B      20  21  22  23
           C      24  25  26  27

当前实现方式

通过unstack/stack转换结构后赋值,存在数据复制开销:

df = df.unstack()
df.loc[:, pd.IndexSlice[:, :, 'A']] = df.loc[:, pd.IndexSlice[:, :, 'B']].values
df = df.stack().reindex(index)

更高效的实现方法

直接通过索引定位目标行与源行,避免数据结构转换和不必要的复制:

方法1:索引匹配直接赋值

# 获取所有A行对应的日期
a_dates = df.index[df.index.get_level_values('idx_2') == 'A'].get_level_values('idx_1')
# 构造对应日期的B行索引
b_indices = list(zip(a_dates, ['B']*len(a_dates)))
# 直接将B行的值赋值给同日期的A行
df.loc[(a_dates, 'A'), :] = df.loc[b_indices, :].values

方法2:groupby+transform批量处理

# 按日期分组,提取每组B行的值并广播,再筛选A行完成赋值
df.loc[(slice(None), 'A'), :] = df.groupby('idx_1').transform(
    lambda group: group.loc[group.index.get_level_values('idx_2') == 'B'].values[0]
)[df.index.get_level_values('idx_2') == 'A']

两种方法均无需对整个DataFrame进行结构转换,直接操作目标数据,大幅减少内存开销和计算时间,尤其适合大尺寸数据集。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.26 04:29:59