【问题标题】:Creating new pandas columns containing count of distinct entries创建包含不同条目计数的新熊猫列
【发布时间】:2016-08-16 01:13:58
【问题描述】:

我正在学习 pandas,并且已经下载了一个包含 2008 年所有奥运奖牌结果的数据集。格式如下:

In[138]: medals.head()
Out[138]: 
      City  Edition     Sport Discipline                      Athlete  NOC  \
9792  Rome     1960  Aquatics     Diving           PHELPS, Brian Eric  GBR   
9793  Rome     1960  Aquatics     Diving        WEBSTER, Robert David  USA   
9794  Rome     1960  Aquatics     Diving         TOBIAN, Gary Milburn  USA   
9795  Rome     1960  Aquatics     Diving               KRUTOVA, Ninel  URS   
9796  Rome     1960  Aquatics     Diving  KRÄMER-ENGEL-GULBIN, Ingrid  EUA   

     Gender         Event Event_gender   Medal  
9792    Men  10m platform            M  Bronze  
9793    Men  10m platform            M    Gold  
9794    Men  10m platform            M  Silver  
9795  Women  10m platform            W  Bronze  
9796  Women  10m platform            W    Gold  

我最初想做的是将其转换为包含 Edition, NOC, Bronze, Silver, Gold 列的数据框,其中铜牌、银牌和金牌是 NOC 在该奥运会上赢得的每个级别奖牌的总数。

目前为止

"""
Analyze historical Olympic performance
"""

import matplotlib.pyplot as plt
import pandas as pd
import matplotlib
matplotlib.style.use('ggplot')

isocodes = pd.read_csv('countrycodes.csv')
for k in ['official_name_en', 'official_name_fr', 'name',
          'ITU', 'MARC', 'WMO', 'DS', 'Dial', 'FIFA', 
          'FIPS', 'GAUL', 'IOC', 'ISO4217-currency_alphabetic_code',
          'ISO4217-currency_country_name', 'ISO4217-currency_minor_unit',
          'ISO4217-currency_name', 'ISO4217-currency_numeric_code',
          'is_independent', 'Capital', 'TLD', 'Languages',
          'geonameid', 'EDGAR' ]:         
          del isocodes[k]     

allmedals = pd.read_excel('medals.xlsx', sheetname='Medals')
ioccodes = pd.read_excel('medals.xlsx', sheetname='Codes')
del ioccodes['Country.1']
codes=pd.merge(ioccodes, isocodes, left_on='ISO code', 
               right_on='ISO3166-1-Alpha-2')

# Convert the year of the games to int from str and
# then filter out all records before 1960

pd.to_numeric(allmedals['Edition'])
medals = allmedals[(allmedals['Edition'] >= 1960)]

# Filter out any duplicates - i.e. for events like the relay
# where each team member is awarded a medal

medals = medals.drop_duplicates(['City', 'Edition', 'Sport', 
                        'Discipline', 'NOC', 'Gender',
                        'Event', 'Event_gender', 'Medal'])

# Now get the medal counts for each Olympics

grouped = medals.groupby(["Edition", "NOC", "Medal"])["Medal"].\
                        count().reset_index(name="count")

知道这一定是一个相当标准的 pandas 操作,而且我快到了:

In[139]: grouped.head()
Out[139]: 
   Edition  NOC   Medal  count
0     1960  ARG  Bronze      1
1     1960  ARG  Silver      1
2     1960  AUS  Bronze      6
3     1960  AUS    Gold      8
4     1960  AUS  Silver      8

但我不知道如何对 grouped 数据框进行分组/聚合。我将不胜感激任何提示(以及任何其他建议 - 例如,使用 deldrop_duplicates() 等是否被视为良好做法?)

【问题讨论】:

  • 你能展示一下最终的数据框应该是什么样子吗?

标签: pandas


【解决方案1】:

UnstackMedal 列:

res = grouped.set_index(['Edition', 'NOC', 'Medal']).unstack('Medal', fill_value=0)
res.columns = res.columns.droplevel(0)

输出(来自您引用的grouped.head()):

Medal        Bronze  Gold  Silver
Edition NOC                      
1960    ARG       1     0       1
        AUS       6     8       8

【讨论】:

  • 从构造grouped的行中删除.reset_index(name="count"),这也可以由res = grouped.unstack('Medal', fill_value=0)完成
  • 快速补充。 res 有一个索引,它由 Edition 和 NOC 列的元组组成。如何更改 res 使其具有五列:Edition、NOC、Bronze、Silver、Gold,而不是元组索引? (我再次确信这一定是基本的)。
  • 最后加一行:res = res.reset_index().
【解决方案2】:

样本df

ioccodes = ['ABC', 'BCD', 'CDE', 'DEF', 'EFG', 'FGH', 'GHI']
idx = pd.MultiIndex.from_product([np.arange(1960, 2016, 4), ['Gold', 'Silver', 'Bronze']], names=['Edition', 'Medal'])
df = pd.DataFrame({'NOC': np.random.choice(ioccodes, len(idx))}, idx).reset_index()

解决方案

df.groupby(['Edition', 'Medal']).NOC.value_counts() \
    .unstack(1).fillna(0).reset_index().rename_axis(None, 1)

【讨论】:

    猜你喜欢
    • 2018-10-01
    • 1970-01-01
    • 2020-03-22
    • 1970-01-01
    • 2021-12-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多