【问题标题】:groupby.mean() doesn't work while sum(), std() and size() all workgroupby.mean() 不起作用,而 sum()、std() 和 size() 都起作用
【发布时间】:2019-08-02 17:35:06
【问题描述】:

我正在关注密歇根大学关于 Python Pandas 数据科学的 MOOC,我在测试中遇到了一些问题。

我必须使用 groupby 函数来计算按大洲分组的 15 个国家的总和、平均值、大小和标准差。

问题是 sum()、std() 和 size() 可以正常工作,但 mean() 不行,我也不知道为什么。

我已经尝试使用dtype=float 指定类型,但我不起作用。

这是我的代码:

# --------- This part is ok, just describing so you can understand --------- #
Top15 = answer_one() # load top 15 countries with most scientific publications

# list of the continents for the top 15 countries
ContinentDict  = {'China':'Asia', 
                  'United States':'North America', 
                  'Japan':'Asia', 
                  'United Kingdom':'Europe', 
                  'Russian Federation':'Europe', 
                  'Canada':'North America', 
                  'Germany':'Europe', 
                  'India':'Asia',
                  'France':'Europe', 
                  'South Korea':'Asia', 
                  'Italy':'Europe', 
                  'Spain':'Europe', 
                  'Iran':'Asia',
                  'Australia':'Australia', 
                  'Brazil':'South America'}

# estimation of the population for each countries 
# by calculating the Energy Supply / Energy Supply per Capita
Top15['PopEst'] = Top15['Energy Supply'] / Top15['Energy Supply per Capita']
Top15 = Top15[['PopEst']]

Top15.reset_index(inplace = True)
Top15['Continent'] = None

# loop that add the coresponding continent to the country
for country in Top15['Country']:
    index_country = ((Top15.loc[Top15['Country'] == country]) # seek country index
                           .index)
    Top15.iloc[index_country,2] = ContinentDict[country] # add continent to country


# ---------- This is the part where I am having problem ---------- #
# create the 'answer' DataFrame
answer = pd.DataFrame(index=['Asia', 'Australia', 
                             'Europe', 'North America', 
                             'South America'], 
                      columns=['size', 'sum', 'mean', 'std'], dtype=float)

grouped = Top15.groupby('Continent')      # group countries by continent

answer['size'] = grouped.size()
answer['sum'] = grouped['PopEst'].sum()
answer['mean'] = grouped['PopEst'].mean()
answer['std'] = grouped['PopEst'].std()

我到了answer['mean'] = grouped['PopEst'].mean(),错误:

DataError:没有要聚合的数字类型

我不知道问题出在哪里。

PopEst 包含数值。比如中国的人口估计是1.36765e+09人。

这是 answer_one() 返回的 DataFrame Top15 我必须处理:

    Country             PopEst      Continent  
0   Australia           2.3316e+07  Australia
1   Brazil              2.05915e+08 South America
2   Canada              3.52399e+07 North America
3   China               1.36765e+09 Asia
4   France              6.38373e+07 Europe
5   Germany             8.03697e+07 Europe
6   India               1.27673e+09 Asia
7   Iran                7.70756e+07 Asia
8   Italy               5.99083e+07 Europe
9   Japan               1.27409e+08 Asia
10  Russian Federation  1.435e+08   Europe
11  South Korea         4.98054e+07 Asia
12  Spain               4.64434e+07 Europe
13  United Kingdom      6.3871e+07  Europe
14  United States       3.17615e+08 North America

这是Top15.to_dict() 回复我的:

{'Country': {0: 'Australia',
  1: 'Brazil',
  2: 'Canada',
  3: 'China',
  4: 'France',
  5: 'Germany',
  6: 'India',
  7: 'Iran',
  8: 'Italy',
  9: 'Japan',
  10: 'Russian Federation',
  11: 'South Korea',
  12: 'Spain',
  13: 'United Kingdom',
  14: 'United States'},
 'PopEst': {0: 23316017.316017315,
  1: 205915254.23728815,
  2: 35239864.86486486,
  3: 1367645161.2903225,
  4: 63837349.39759036,
  5: 80369696.96969697,
  6: 1276730769.2307692,
  7: 77075630.25210084,
  8: 59908256.880733944,
  9: 127409395.97315437,
  10: 143500000.0,
  11: 49805429.864253394,
  12: 46443396.2264151,
  13: 63870967.741935484,
  14: 317615384.61538464},
 'Continent': {0: 'Australia',
  1: 'South America',
  2: 'North America',
  3: 'Asia',
  4: 'Europe',
  5: 'Europe',
  6: 'Asia',
  7: 'Asia',
  8: 'Europe',
  9: 'Asia',
  10: 'Europe',
  11: 'Asia',
  12: 'Europe',
  13: 'Europe',
  14: 'North America'}}

【问题讨论】:

  • answer_one() 是什么? PopEst 是否包含数值?:(
  • answer_one() 是(如您所料)以前的答案。它只返回一个包含 15 个国家(出版物最多的快递员)的 DataFrame。是的,PopEst 包含数值。它是每 15 个国家的人口估计数。我找到了一种解决方法,但我仍然不知道为什么 mean() 不起作用。这是我的工作:answer['mean'] = grouped['PopEst'].sum() / grouped['PopEst'].size()
  • 我们无权访问answer_one()。您可以简单地发布导致问题的数据框吗?
  • 我更新了我的帖子。导致问题的 DataFrame 是 Top15。问题是否来自仅存在 1 个国家/地区 的大陆,因此无法应用均值,因为只有一个值可以计算均值?
  • 你能复制粘贴或top15.to_dict() 并发布输出吗?从图片中再现数据帧非常困难。 (请参阅this 寻求帮助。)

标签: python pandas pandas-groupby


【解决方案1】:

这是Pandas 的一个bug,即使数据不是数字,Pandas 仍然在 groupby 中进行 sum 和 prod 计算。查了源码,bug出现in line 1373site-packages\pandas\core\groupby\groupby.py。它写道:

                except Exception:
                    pass

如果您打印错误,您可能还会发现“没有要聚合的数字类型”。

作为一种临时解决方案,您可以在进行任何计算之前将数据更改为数值,方法是:

df['column'] = pd.to_numeric(df['column'])

有些帖子可能会告诉您在pd.to_numeric 中添加errors='coerce',这样非数字元素将被na 替换并且不会引发错误。但是,在许多情况下,这意味着数据中存在一些错误。我们需要修复数据而不是消除错误。

【讨论】:

    【解决方案2】:

    这是我能想到的最好的了

        final["Sum"]= final.groupby(['Cont_bin']).PopEst.transform('sum')
        final['Sum'] = pd.to_numeric(final['Sum'])
        final["PopEst"]= pd.to_numeric(final["PopEst"])
        final["Size"]=pd.to_numeric(final["Size"])
        final["Mean"]=final.groupby(['Cont_bin', 'Size']).PopEst.transform('mean')
       
        return(final)
    

    您需要将平均值强制转换为数字以获得标准差

    【讨论】:

      猜你喜欢
      • 2018-10-18
      • 1970-01-01
      • 2018-07-19
      • 1970-01-01
      • 2013-08-19
      • 2014-01-19
      • 2014-04-29
      • 2013-06-01
      • 1970-01-01
      相关资源
      最近更新 更多