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

如何在Pandas DataFrame中按不同行的值执行列值除法运算?

解决方案

步骤1:提取分组基准值

先获取每个(Index1, Index2)分组下Index3=C0对应的value1和value2,作为后续计算的基准:

import pandas as pd
import numpy as np

# 假设你的多层索引DataFrame已创建为df
# 提取C0行的基准值并重命名列,避免和原列冲突
base_values = df.xs('C0', level='Index3')[['value1', 'value2']].rename(
    columns={'value1': 'base_v1', 'value2': 'base_v2'}
)

步骤2:合并基准值到原数据

将基准值按Index1和Index2合并到原DataFrame,确保每行都能匹配到对应分组的C0基准值:

df = df.join(base_values, on=['Index1', 'Index2'])

步骤3:分场景计算目标值

用np.where区分两种逻辑,分别执行除法运算:

# 计算新的value1
df['value1'] = np.where(
    df.index.get_level_values('Index3') == 'C0',
    df['value1'] / df['total'],  # C0场景:自身值除以total
    df['value1'] / df['base_v1']  # C1/C2场景:自身值除以同组C0的value1
)

# 计算新的value2
df['value2'] = np.where(
    df.index.get_level_values('Index3') == 'C0',
    df['value2'] / df['total'],  # C0场景:自身值除以total
    df['value2'] / df['base_v2']  # C1/C2场景:自身值除以同组C0的value2
)

# 移除临时基准列(可选)
df = df.drop(columns=['base_v1', 'base_v2'])

可选:显示分数格式字符串

如果需要像示例那样以分子/分母的字符串形式展示结果(而非浮点数值),可以修改计算逻辑为字符串拼接:

# 重新提取基准值(若已删除需重新执行)
base_values = df.xs('C0', level='Index3')[['value1', 'value2']].rename(
    columns={'value1': 'base_v1', 'value2': 'base_v2'}
)
df = df.join(base_values, on=['Index1', 'Index2'])

# 生成value1的分数字符串
df['value1'] = np.where(
    df.index.get_level_values('Index3') == 'C0',
    df['value1'].astype(str) + '/' + df['total'].astype(str),
    df['value1'].astype(str) + '/' + df['base_v1'].astype(str)
)

# 生成value2的分数字符串
df['value2'] = np.where(
    df.index.get_level_values('Index3') == 'C0',
    df['value2'].astype(str) + '/' + df['total'].astype(str),
    df['value2'].astype(str) + '/' + df['base_v2'].astype(str)
)

df = df.drop(columns=['base_v1', 'base_v2'])

执行后得到的DataFrame会完全符合需求逻辑:C0行的value1/value2为自身值与total的比值,C1/C2行则为自身值与同组C0对应值的比值。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.09 10:05:34