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

如何为MultiIndex DataFrame按多条件添加计算生成的新行

向MultiIndex DataFrame添加满足多条件的新行

我来帮你搞定这个需求,咱们一步步实现你要的功能:

首先是完整的可运行代码

import pandas as pd
import numpy as np

# 构建你提供的初始DataFrame
def mklbl(prefix, n): return ["%s%s" % (prefix, i) for i in range(n)]

miindex = pd.MultiIndex.from_product([mklbl('A', 3), mklbl('B', 4), ], names=['A','B'])
micolumns = pd.MultiIndex.from_tuples([('a', 'foo'), ('a', 'bar'), ('b', 'foo'), ('b', 'bah')], names=['lvl0', 'lvl1'])
df = pd.DataFrame(np.random.randint(100, size=len(miindex) * len(micolumns)) .reshape((len(miindex), len(micolumns))), index=miindex, columns=micolumns).sort_index().sort_index(axis=1)
df = df.drop([('A2','B2'),('A2','B3')])

# ------------------- 核心处理逻辑 -------------------
# 1. 筛选出同时包含B2和B3的A分组(只有A0、A1符合)
valid_a_groups = [
    a for a in df.index.get_level_values('A').unique()
    if all(b in df.loc[a].index for b in ['B2', 'B3'])
]

# 2. 生成要添加的B4行
new_rows = []
for a in valid_a_groups:
    # 获取当前A分组下B2和B3的数值
    b2_vals = df.loc[(a, 'B2')]
    b3_vals = df.loc[(a, 'B3')]
    
    # 按条件计算B4的值:B3 < B2时取B3/B2,否则为0,保留3位小数
    b4_vals = np.where(b3_vals < b2_vals, b3_vals / b2_vals, 0).round(3)
    
    # 构造新的行,指定MultiIndex名称为(A, 'B4')
    new_row = pd.Series(b4_vals, index=df.columns, name=(a, 'B4'))
    new_rows.append(new_row)

# 3. 合并原DataFrame和新行,重新排序索引得到最终结果
final_df = pd.concat([df] + new_rows).sort_index()
print(final_df)

代码逻辑解释

  1. 筛选有效A分组:我们只需要处理那些同时存在B2和B3的A分组(A0和A1),这里用列表推导式直接检查每个A分组的子索引是否包含B2和B3,比通过行数判断更严谨。
  2. 计算B4行数值:对每个有效分组,提取B2和B3的列值,用np.where实现条件判断——当B3的数值小于B2时,计算两者的比值,否则设为0,同时保留三位小数和你的示例格式一致。
  3. 合并并排序:把生成的B4行和原DataFrame合并,最后重新排序索引,保证结构和原DataFrame一致。

运行这段代码后,你就能得到和示例完全一致的结果,A2因为没有B2和B3,所以不会添加B4行。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.13 07:30:23