财务数据宽表转长表报错KeyError: 'Group Item' 求助
问题分析与修正方案
错误原因
代码触发KeyError: 'Group Item'的核心问题:
- 循环处理财务指标组时,用
pd.concat(melted_dfs, axis=1)横向拼接多个melt结果,导致生成重复的Variable列(Pandas会自动给重复列名加后缀,比如Variable、Variable.1等) - 后续尝试通过
result_table['Variable']获取列时,该列名已不存在,因此抛出KeyError - 横向拼接的逻辑本身不符合需求,应将不同指标组的数据纵向合并后再统一处理年份和指标分类
修正后的代码
import pandas as pd # 定义各财务指标列组 sales_columns = ['Sales0', 'Sales1', 'Sales2', 'Sales3', 'Sales4', 'Sales5', 'Sales6', 'Sales7', 'Sales8', 'Sales9', 'Sales10', 'Sales11'] net_income_columns = ['NetInc0', 'NetInc1', 'NetInc2', 'NetInc3', 'NetInc4', 'NetInc5', 'NetInc6', 'NetInc7', 'NetInc8', 'NetInc9', 'NetInc10', 'NetInc11'] ebit_columns = ['EBIT0', 'EBIT1', 'EBIT2', 'EBIT3', 'EBIT4', 'EBIT5', 'EBIT6', 'EBIT7', 'EBIT8', 'EBIT9', 'EBIT10', 'EBIT11'] equity_columns = ['Equity0', 'Equity1', 'Equity2', 'Equity3', 'Equity4', 'Equity5', 'Equity6', 'Equity7', 'Equity8', 'Equity9', 'Equity10', 'Equity11'] tangible_assets_columns = ['TangibleAssets0', 'TangibleAssets1', 'TangibleAssets2', 'TangibleAssets3', 'TangibleAssets4', 'TangibleAssets5', 'TangibleAssets6', 'TangibleAssets7', 'TangibleAssets8', 'TangibleAssets9', 'TangibleAssets10', 'TangibleAssets11'] # 建立指标组名称与列的映射,用于生成Group Item column_group_map = { 'Sales': sales_columns, 'Net Income': net_income_columns, 'EBIT': ebit_columns, 'Equity': equity_columns, 'Tangible Assets': tangible_assets_columns } # 年份与列名后缀对应:Sales0→2023,Sales1→2022...以此类推 years = ['2023', '2022', '2021', '2020', '2019', '2018', '2017', '2016', '2015', '2014', '2013', '2012'] result_tables = [] # 先对全量数据做批量melt处理,提升效率 melted_dfs = [] for group_name, columns in column_group_map.items(): df_melt = pd.melt(df, id_vars=['Symbol'], value_vars=columns, var_name='Metric_Year', value_name='Value') # 从列名后缀提取年份索引,匹配对应年份 df_melt['Year'] = df_melt['Metric_Year'].apply(lambda x: years[int(x[-1])]) df_melt['Group Item'] = group_name melted_dfs.append(df_melt) # 纵向合并所有指标组数据 combined_df = pd.concat(melted_dfs, ignore_index=True) # 按公司生成标准化财务报告 for company in df['Symbol'].unique(): company_data = combined_df[combined_df['Symbol'] == company].copy() # 转成宽表:指标为行,年份为列 company_report = company_data.pivot(index='Group Item', columns='Year', values='Value').reset_index() # 调整列顺序,适配阅读习惯 company_report = company_report[['Group Item'] + years] # 添加公司标识(可选,用于Streamlit展示时区分) company_report['Company Symbol'] = company result_tables.append(company_report) # 测试输出(Streamlit展示时替换为st.dataframe(report)即可) for idx, report in enumerate(result_tables, 1): print(f"\nCompany {idx} Financial Report:\n{report.to_string(index=False)}")
关键优化点
- 合并逻辑修正:将横向拼接改为纵向合并,彻底解决重复列名导致的KeyError
- 效率提升:先对全量数据做一次melt,再按公司筛选,避免循环处理数千行数据带来的性能损耗
- 格式适配:最终生成的宽表可直接在Streamlit中用
st.dataframe()展示,符合单公司财务报告的阅读逻辑 - 年份映射自动化:通过列名后缀数字自动匹配对应年份,无需手动关联
内容的提问来源于stack exchange,提问作者mpauls7
相关产品推荐
相关产品推荐

