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

如何在DataFrame中使各公司数据乘以对应Total General值且保留该值不变

问题解决:透视表数值按年份乘以对应Total General值

问题描述

通过代码生成了以Company为行索引、Year(2023/2024)为列索引的透视表,需求是:

  • Amazon、Chedraui等公司的各年份数值,乘以对应年份的Total General数值
  • Total General行的数值保持不变

尝试实现时触发KeyError: "None of ['Year'] are in the columns",原因是透视表的Year是列索引,而非普通DataFrame列,原代码错误地将其当作普通列处理。

错误代码分析

原代码中df_3 = pd.DataFrame(df_2).set_index('Year')这一行存在问题:df_2的Year是列名(即列索引),不是DataFrame的普通列,因此无法通过set_index('Year')找到对应列,导致KeyError。

正确解决方案

核心思路

  1. 提取Total General行的数值,作为各年份的乘数
  2. 对非Total General的公司行,让每一列(年份)的数值乘以对应年份的乘数
  3. 将处理后的公司行与原Total General行合并,得到最终结果

修正后的完整代码

import pandas as pd
import matplotlib.pyplot as plt
from rich import print

def plot_som_charts(catcp_filter,mesesin):
    df = pd.read_csv('data_graf_som.csv')

    # 数据过滤
    df['Date'] = pd.to_datetime(df['Month.1'])
    df = df[(df['Year'] == 2023) & (df['Date'].dt.month <= mesesin) |
            (df['Year'] == 2024) & (df['Date'].dt.month <= mesesin)]
    df = df[df['CATCP'] == catcp_filter]  

    # 计算各公司YTD数据
    grouped = df.groupby(['Year', 'Company']).agg({
        ' CPUSD': 'sum',
        ' SalesCD': 'sum'
    }).reset_index()

    # 计算年度Total General
    total_general = grouped.groupby('Year').agg({
        ' CPUSD': 'sum',
        ' SalesCD': 'sum'
    }).reset_index()
    total_general['Company'] = 'Total General'

    # 合并数据并计算SOM
    result = pd.concat([grouped, total_general], ignore_index=True)
    result = result.sort_values(by=['Year', 'Company']).reset_index(drop=True)
    result['SOM'] = result[' CPUSD'] / result[' SalesCD']

    # 生成透视表
    pivot_df_year = result.pivot(index='Company', columns='Year', values='SOM')
    return pivot_df_year

# 生成原始透视表
df_2 = plot_som_charts('TP',6)   

# ==================== 核心处理部分 ====================
# 提取Total General作为各年份的乘数
total_gen_values = df_2.loc['Total General']

# 筛选非Total General的公司行,进行乘法运算
other_companies = df_2.drop('Total General') * total_gen_values

# 合并处理后的公司行与原Total General行
df_3 = pd.concat([other_companies, df_2.loc[['Total General']]])

# 保持原行顺序(可选,根据需求调整)
df_3 = df_3.reindex(df_2.index)

print(df_3)

关键代码解释

  • total_gen_values = df_2.loc['Total General']:直接提取Total General行的所有年份数值,得到一个Series,索引为年份
  • df_2.drop('Total General') * total_gen_values:利用Pandas的广播机制,非Total General行的每一列(年份)都会自动对应乘以total_gen_values中相同年份的数值
  • pd.concat([other_companies, df_2.loc[['Total General']]]):将处理后的公司数据与原Total General行合并,保证Total General数值不变
  • df_3.reindex(df_2.index):可选步骤,用于保持原始透视表的行顺序(比如让Total General仍在最后)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.19 07:46:04