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

绘制奥运奖牌饼图时遇AttributeError与ValueError问题求助

解决奥运奖牌饼图Python代码中的两个报错问题

我来帮你逐个拆解并解决这两个报错:

第一个错误:ValueError: Length mismatch: Expected axis has 2 elements, new values have 3 elements

问题根源

看你代码里这段操作:

final_df.reset_index(inplace=True)
final_df.columns=('location','Total cases','Total Deaths')

在执行reset_index之后,final_df其实只有2列——原来的索引列Country,加上你通过iloc[:,[14]]选取的TotalMedal列。但你给了3个列名,列数和列名数量不匹配,自然就触发了这个错误。

修复方法

如果你只是需要国家和总奖牌数这两列,要么直接跳过手动改列名的步骤(重置索引后列名会自动是Country和TotalMedal,完全贴合你的需求),要么把列名改成对应2个元素的元组:

# 方案1:保留默认列名,最省心
final_df.reset_index(inplace=True)

# 方案2:如果一定要自定义列名,用2个元素的元组
final_df.columns=('Country', 'TotalMedal')

第二个错误:AttributeError: 'DataFrameGroupBy' object has no attribute 'sort_values'

问题根源

这个错误说明你在一个**分组后的对象(DataFrameGroupBy)**上调用了sort_values,但分组对象本身没有这个方法。结合你的代码来看,大概率是两种情况之一:

  1. 你可能在代码里做了groupby分组操作(但没贴出来),直接对分组结果调用sort_values;
  2. 读取CSV时的分隔符设置错了——你用了sep=' ',但奥运数据的CSV一般是逗号分隔的,这会导致pandas读取的DataFrame结构混乱,甚至意外出现类似分组的异常对象。

修复方法

  • 如果是第一种情况(确实做了分组):先对分组结果做聚合(比如求和、取均值)得到普通DataFrame,再调用sort_values:
    # 示例:按国家分组后聚合总奖牌数,再排序
    grouped_df = df.groupby('Country')['TotalMedal'].sum().reset_index()
    sorted_df = grouped_df.sort_values(by='TotalMedal')
    
  • 如果是第二种情况(分隔符错误):把sep=' '改成逗号分隔,或者让pandas自动推断分隔符:
    # 方法1:让pandas自动推断分隔符
    df = pd.read_csv('data.csv', index_col=False, skipinitialspace=True, 
                     error_bad_lines=False, encoding='unicode_escape')
    
    # 方法2:明确指定逗号分隔
    df = pd.read_csv('data.csv', sep=',', index_col=False, skipinitialspace=True, 
                     error_bad_lines=False, encoding='unicode_escape')
    

完整修正后的代码

结合你的需求(绘制Top10国家的奥运奖牌饼图),我整理了一份优化后的完整代码,同时去掉了冗余操作:

import pandas as pd
import matplotlib.pyplot as plt

def piechart1():
    # 读取CSV,修正分隔符为逗号(适配大多数奥运数据格式)
    df = pd.read_csv('data.csv', sep=',', index_col=False, skipinitialspace=True, 
                     error_bad_lines=False, encoding='unicode_escape')
    
    # 直接选取需要的列(Country和TotalMedal),比用iloc硬编码列索引更鲁棒
    df_filtered = df[['Country', 'TotalMedal']]
    
    # 按总奖牌数降序排序,取前10个国家
    final_df = df_filtered.sort_values(by='TotalMedal', ascending=False).head(10)
    
    # 准备饼图所需的数据
    countries = final_df['Country']
    tmedals = final_df['TotalMedal']
    
    # 绘制饼图
    plt.pie(tmedals, labels=countries, explode=(0.1, 0, 0, 0, 0, 0, 0, 0, 0, 0), 
            shadow=True, autopct='%0.1f%%')
    plt.title("Olympics Data Analysis\nTop 10 Countries by Total Medals", color='b', fontsize=12)
    plt.gcf().canvas.set_window_title("OLMPICS ANALYSIS")
    plt.show()

# 调用函数生成饼图
piechart1()

额外优化说明

  • 删掉了没用的csv和numpy导入(你的代码里没用到它们);
  • 用列名直接选数据代替iloc[:,[14]],避免因为CSV列顺序变化导致的错误;
  • 明确按降序排序并取前10,确保饼图展示的是真正的Top10国家;
  • 修正了标题的拼写格式,看起来更规范。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.09 00:12:41