Pivot tables#
Pivoting of data is the process of aggregating data across two or more categorical variables.
Closely related are:
Group by, where the number of categorical variables is flexible.
Cross tabulation, which is basically pivoting, but with different defaults and parameters.
In Pandas, pivot tables are based on
values: what to aggregate
index and column: layout of result, and
aggfunc: how to aggregate.
Sales data from Power BI examples#
# Read SalesData.xlsx
import pandas as pd
df = pd.read_excel('../../data/SalesData.xlsx', skiprows=4, header=0)
print(df.shape)
df.head()
(260096, 10)
OrderDate | OrderNumber | ProductKey | SalespersonKey | Salesperson | Supervisor | Manager | Channel | Quantity | UnitPrice | |
---|---|---|---|---|---|---|---|---|---|---|
0 | 2019-01-12 | 1492762 | 1420 | 265 | Julio Lima | Diogo Carvalho | Gabriel Azevedo | Distributor | 6 | 4.44 |
1 | 2019-01-12 | 1492762 | 1073 | 265 | Julio Lima | Diogo Carvalho | Gabriel Azevedo | Distributor | 6 | 8.83 |
2 | 2019-01-12 | 1492762 | 264 | 265 | Julio Lima | Diogo Carvalho | Gabriel Azevedo | Distributor | 10 | 0.96 |
3 | 2019-01-13 | 1492719 | 1154 | 265 | Julio Lima | Diogo Carvalho | Gabriel Azevedo | Distributor | 6 | 2.92 |
4 | 2019-01-13 | 1492719 | 1527 | 265 | Julio Lima | Diogo Carvalho | Gabriel Azevedo | Distributor | 6 | 2.81 |
# Add a column giving the total price
df['TotalPrice'] = df['Quantity'] * df['UnitPrice']
df.head()
OrderDate | OrderNumber | ProductKey | SalespersonKey | Salesperson | Supervisor | Manager | Channel | Quantity | UnitPrice | TotalPrice | |
---|---|---|---|---|---|---|---|---|---|---|---|
0 | 2019-01-12 | 1492762 | 1420 | 265 | Julio Lima | Diogo Carvalho | Gabriel Azevedo | Distributor | 6 | 4.44 | 26.64 |
1 | 2019-01-12 | 1492762 | 1073 | 265 | Julio Lima | Diogo Carvalho | Gabriel Azevedo | Distributor | 6 | 8.83 | 52.98 |
2 | 2019-01-12 | 1492762 | 264 | 265 | Julio Lima | Diogo Carvalho | Gabriel Azevedo | Distributor | 10 | 0.96 | 9.60 |
3 | 2019-01-13 | 1492719 | 1154 | 265 | Julio Lima | Diogo Carvalho | Gabriel Azevedo | Distributor | 6 | 2.92 | 17.52 |
4 | 2019-01-13 | 1492719 | 1527 | 265 | Julio Lima | Diogo Carvalho | Gabriel Azevedo | Distributor | 6 | 2.81 | 16.86 |
# Use Pandas groupby() to group by Channel and sum the TotalPrice
df1 = df.groupby('Channel')['TotalPrice'].sum()
df1
Channel
Distributor 6098515.78
Online 3113650.20
Retail 8697066.51
Name: TotalPrice, dtype: float64
# Use Pandas pivot_table() to group by Channel and Manager and sum the TotalPrice
df2 = df.pivot_table(index='Channel', columns='Manager', values='TotalPrice', aggfunc='sum')
df2
Manager | Gabriel Azevedo | Victor Castro |
---|---|---|
Channel | ||
Distributor | 6098515.78 | NaN |
Online | 3113650.20 | NaN |
Retail | NaN | 8697066.51 |
# Exchange aggfunc='sum' for aggfunc='count' to confirm that the dataset is not very suitable for this type of analysis
df2 = df.pivot_table(index='Channel', columns='Manager', values='TotalPrice', aggfunc='count')
df2
Manager | Gabriel Azevedo | Victor Castro |
---|---|---|
Channel | ||
Distributor | 91585.0 | NaN |
Online | 59442.0 | NaN |
Retail | NaN | 109069.0 |
Olympic athletes and results#
Kaggle dataset scraped from www.sports-reference.com/
# Read the athlete_events.csv file
import pandas as pd
athletes = pd.read_csv('../../data/athlete_events.csv')
print(athletes.shape)
athletes.head()
(271116, 15)
ID | Name | Sex | Age | Height | Weight | Team | NOC | Games | Year | Season | City | Sport | Event | Medal | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0 | 1 | A Dijiang | M | 24.0 | 180.0 | 80.0 | China | CHN | 1992 Summer | 1992 | Summer | Barcelona | Basketball | Basketball Men's Basketball | NaN |
1 | 2 | A Lamusi | M | 23.0 | 170.0 | 60.0 | China | CHN | 2012 Summer | 2012 | Summer | London | Judo | Judo Men's Extra-Lightweight | NaN |
2 | 3 | Gunnar Nielsen Aaby | M | 24.0 | NaN | NaN | Denmark | DEN | 1920 Summer | 1920 | Summer | Antwerpen | Football | Football Men's Football | NaN |
3 | 4 | Edgar Lindenau Aabye | M | 34.0 | NaN | NaN | Denmark/Sweden | DEN | 1900 Summer | 1900 | Summer | Paris | Tug-Of-War | Tug-Of-War Men's Tug-Of-War | Gold |
4 | 5 | Christine Jacoba Aaftink | F | 21.0 | 185.0 | 82.0 | Netherlands | NED | 1988 Winter | 1988 | Winter | Calgary | Speed Skating | Speed Skating Women's 500 metres | NaN |
# Check average weight of athletes
athlete_weight = athletes['Weight'].mean()
# Print athlete_weight with 2 decimal places and kg suffix
print('Average weight of athletes: {:.2f} kg'.format(athlete_weight))
Average weight of athletes: 70.70 kg
# Check average weight of athletes for each year
athlete_weight_by_year = athletes.groupby('Year')['Weight'].mean()
# Plot athlete_weight_by_year using kind='bar'
import matplotlib.pyplot as plt
athlete_weight_by_year.plot(kind='bar', figsize=(12, 4))
# Add horizontal grid lines to the plot
plt.grid(axis='y')
plt.show()
# Check average weight of athletes for each sport and drop NA values
athlete_weight_by_sport = athletes.groupby('Sport')['Weight'].mean().dropna()
athlete_weight_by_sport
Sport
Alpine Skiing 72.068110
Archery 70.011135
Art Competitions 75.290909
Athletics 69.249287
Badminton 68.171439
Baseball 85.707792
Basketball 85.777053
Beach Volleyball 79.089219
Biathlon 66.631419
Bobsleigh 89.250678
Boxing 65.249890
Canoeing 76.492615
Cross Country Skiing 65.877670
Curling 72.131707
Cycling 70.067944
Diving 60.572741
Equestrianism 67.803975
Fencing 71.387538
Figure Skating 59.543651
Football 70.446834
Freestyle Skiing 67.026835
Golf 71.194444
Gymnastics 56.916553
Handball 81.497151
Hockey 69.169909
Ice Hockey 80.810364
Judo 78.759867
Lacrosse 76.714286
Luge 77.264151
Modern Pentathlon 70.279540
Motorboating 77.000000
Nordic Combined 66.909560
Rhythmic Gymnastics 48.760976
Rowing 80.035863
Rugby 77.533333
Rugby Sevens 78.939799
Sailing 75.975154
Shooting 74.027877
Short Track Speed Skating 64.310484
Skeleton 74.166667
Ski Jumping 65.079014
Snowboarding 69.549189
Softball 67.471655
Speed Skating 70.026352
Swimming 70.588492
Synchronized Swimming 55.863529
Table Tennis 64.956449
Taekwondo 68.007475
Tennis 70.802291
Trampolining 59.322148
Triathlon 61.817490
Tug-Of-War 95.615385
Volleyball 78.900214
Water Polo 84.566446
Weightlifting 78.726663
Wrestling 75.495570
Name: Weight, dtype: float64
# Make a pivot table of athlete weights by sport and year
athlete_weight_sport_year = athletes.pivot_table(index='Sport', columns='Year', values='Weight', aggfunc='mean')
athlete_weight_sport_year
Year | 1896 | 1900 | 1904 | 1906 | 1908 | 1912 | 1920 | 1924 | 1928 | 1932 | ... | 1998 | 2000 | 2002 | 2004 | 2006 | 2008 | 2010 | 2012 | 2014 | 2016 |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
Sport | |||||||||||||||||||||
Alpine Skiing | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | ... | 75.080645 | NaN | 75.906872 | NaN | 75.672104 | NaN | 75.334802 | NaN | 74.851455 | NaN |
Archery | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | ... | NaN | 70.151961 | NaN | 70.391509 | NaN | 72.683938 | NaN | 71.795000 | NaN | 72.232323 |
Art Competitions | NaN | NaN | NaN | NaN | NaN | NaN | NaN | 79.333333 | 86.500000 | 73.955556 | ... | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN |
Athletics | 70.068966 | 74.526316 | 73.714286 | 74.739726 | 73.819444 | 72.239960 | 71.402913 | 69.778533 | 69.838565 | 70.306452 | ... | NaN | 69.710613 | NaN | 69.894204 | NaN | 69.446746 | NaN | 68.939536 | NaN | 67.385732 |
Badminton | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | ... | NaN | 67.475556 | NaN | 68.132500 | NaN | 67.885246 | NaN | 68.016667 | NaN | 68.970588 |
Baseball | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | ... | NaN | 85.476190 | NaN | 88.026178 | NaN | 88.239474 | NaN | NaN | NaN | NaN |
Basketball | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | ... | NaN | 86.639860 | NaN | 86.857143 | NaN | 87.195652 | NaN | 87.409894 | NaN | 87.867857 |
Beach Volleyball | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | ... | NaN | 78.718750 | NaN | 79.520833 | NaN | 79.875000 | NaN | 79.505263 | NaN | 78.583333 |
Biathlon | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | ... | 65.912833 | NaN | 65.627660 | NaN | 65.083587 | NaN | 65.147877 | NaN | 65.371148 | NaN |
Bobsleigh | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | 84.600000 | 58.333333 | ... | 93.218905 | NaN | 91.995781 | NaN | 91.890052 | NaN | 92.927136 | NaN | 93.734234 | NaN |
Boxing | NaN | NaN | 61.368421 | NaN | 73.000000 | NaN | 55.000000 | 73.571429 | 63.900000 | 66.416667 | ... | NaN | 66.092105 | NaN | 66.101786 | NaN | 66.369258 | NaN | 67.158537 | NaN | 66.605166 |
Canoeing | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | ... | NaN | 78.042411 | NaN | 77.716590 | NaN | 77.951389 | NaN | 76.269417 | NaN | 77.009153 |
Cross Country Skiing | NaN | NaN | NaN | NaN | NaN | NaN | NaN | 68.909091 | 69.294118 | 67.285714 | ... | 65.300000 | NaN | 65.586162 | NaN | 65.816276 | NaN | 65.844228 | NaN | 66.537012 | NaN |
Curling | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | ... | 72.712500 | NaN | 72.791667 | NaN | 72.186813 | NaN | 71.797753 | NaN | 70.555556 | NaN |
Cycling | NaN | NaN | NaN | 67.583333 | 72.769231 | 76.000000 | 71.250000 | 76.000000 | 70.692308 | 70.000000 | ... | NaN | 69.757282 | NaN | 69.505618 | NaN | 69.916149 | NaN | 69.173567 | NaN | 68.377473 |
Diving | NaN | NaN | NaN | 76.000000 | 76.000000 | 76.000000 | 68.000000 | 62.666667 | NaN | NaN | ... | NaN | 59.710084 | NaN | 60.647959 | NaN | 60.483516 | NaN | 59.843575 | NaN | 60.595506 |
Equestrianism | NaN | NaN | NaN | NaN | NaN | 63.000000 | NaN | 66.142857 | 65.400000 | NaN | ... | NaN | 67.254237 | NaN | 68.340599 | NaN | 67.804217 | NaN | 67.715116 | NaN | 67.900285 |
Fencing | NaN | 75.000000 | NaN | 79.000000 | 80.000000 | 81.000000 | 76.529412 | 74.166667 | 76.142857 | 76.812500 | ... | NaN | 72.845481 | NaN | 72.351097 | NaN | 70.359133 | NaN | 69.742690 | NaN | 71.228986 |
Figure Skating | NaN | NaN | NaN | NaN | NaN | NaN | 65.500000 | 58.666667 | 58.750000 | 54.333333 | ... | 60.034965 | NaN | 60.516129 | NaN | 60.446043 | NaN | 60.623288 | NaN | 60.355263 | NaN |
Football | NaN | NaN | 60.000000 | NaN | 99.000000 | 72.600000 | 75.181818 | 72.033333 | 72.187500 | NaN | ... | NaN | 70.077957 | NaN | 69.132029 | NaN | 69.791045 | NaN | 68.147651 | NaN | 68.358051 |
Freestyle Skiing | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | ... | 65.300000 | NaN | 65.528571 | NaN | 65.745690 | NaN | 69.263314 | NaN | 67.486275 | NaN |
Golf | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | ... | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | 71.194444 |
Gymnastics | 68.000000 | 64.000000 | 69.400000 | 76.250000 | 68.833333 | 73.000000 | 65.000000 | NaN | 64.102564 | 61.222222 | ... | NaN | 54.802295 | NaN | 55.196351 | NaN | 55.163432 | NaN | 56.299338 | NaN | 56.532089 |
Handball | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | ... | NaN | 80.565217 | NaN | 82.268293 | NaN | 81.593373 | NaN | 82.156342 | NaN | 83.269122 |
Hockey | NaN | NaN | NaN | NaN | 89.000000 | NaN | NaN | NaN | NaN | 79.000000 | ... | NaN | 69.285303 | NaN | 68.928977 | NaN | 68.627907 | NaN | 68.986523 | NaN | 68.802564 |
Ice Hockey | NaN | NaN | NaN | NaN | NaN | NaN | 74.000000 | 78.100000 | 75.857143 | 73.631579 | ... | 81.295775 | NaN | 81.230769 | NaN | 81.042986 | NaN | 81.101190 | NaN | 81.663657 | NaN |
Judo | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | ... | NaN | 77.875315 | NaN | 78.612272 | NaN | 79.410390 | NaN | 77.479112 | NaN | 77.203704 |
Lacrosse | NaN | NaN | 76.714286 | NaN | NaN | NaN | NaN | NaN | NaN | NaN | ... | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN |
Luge | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | ... | 78.979381 | NaN | 78.871795 | NaN | 77.490741 | NaN | 79.514019 | NaN | 79.590909 | NaN |
Modern Pentathlon | NaN | NaN | NaN | NaN | NaN | NaN | NaN | 71.000000 | 67.000000 | 72.000000 | ... | NaN | 66.187500 | NaN | 66.703125 | NaN | 66.208333 | NaN | 66.180556 | NaN | 66.333333 |
Motorboating | NaN | NaN | NaN | NaN | 77.000000 | NaN | NaN | NaN | NaN | NaN | ... | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN |
Nordic Combined | NaN | NaN | NaN | NaN | NaN | NaN | NaN | 68.500000 | 72.000000 | 63.250000 | ... | 66.000000 | NaN | 66.184000 | NaN | 66.231884 | NaN | 65.610687 | NaN | 64.829268 | NaN |
Rhythmic Gymnastics | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | ... | NaN | 46.642857 | NaN | 49.392857 | NaN | 50.852632 | NaN | 51.571429 | NaN | 50.395833 |
Rowing | NaN | 65.333333 | 75.000000 | 79.000000 | 74.103448 | 73.052632 | 76.923077 | 69.947368 | 77.190476 | 76.000000 | ... | NaN | 80.716578 | NaN | 80.703041 | NaN | 80.768817 | NaN | 80.831810 | NaN | 79.872263 |
Rugby | NaN | 71.666667 | NaN | NaN | NaN | NaN | 74.333333 | 80.111111 | NaN | NaN | ... | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN |
Rugby Sevens | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | ... | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | 78.939799 |
Sailing | NaN | NaN | NaN | NaN | NaN | 82.000000 | 74.000000 | NaN | 90.000000 | 63.500000 | ... | NaN | 76.350000 | NaN | 73.049875 | NaN | 73.327500 | NaN | 74.128686 | NaN | 71.266667 |
Shooting | NaN | NaN | NaN | NaN | NaN | 109.000000 | NaN | 89.545455 | NaN | NaN | ... | NaN | 73.004188 | NaN | 74.369176 | NaN | 74.670157 | NaN | 72.731397 | NaN | 73.195212 |
Short Track Speed Skating | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | ... | 64.284153 | NaN | 64.870968 | NaN | 64.213389 | NaN | 63.952381 | NaN | 64.303371 | NaN |
Skeleton | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | 88.000000 | NaN | ... | NaN | NaN | 74.526316 | NaN | 75.309524 | NaN | 72.893617 | NaN | 73.826087 | NaN |
Ski Jumping | NaN | NaN | NaN | NaN | NaN | NaN | NaN | 70.000000 | 67.666667 | 60.400000 | ... | 63.079268 | NaN | 62.343750 | NaN | 61.574257 | NaN | 61.541667 | NaN | 61.165803 | NaN |
Snowboarding | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | ... | 68.039370 | NaN | 69.500000 | NaN | 69.934010 | NaN | 70.100000 | NaN | 69.623762 | NaN |
Softball | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | ... | NaN | 68.025000 | NaN | 67.991525 | NaN | 67.783333 | NaN | NaN | NaN | NaN |
Speed Skating | NaN | NaN | NaN | NaN | NaN | NaN | NaN | 66.083333 | 70.800000 | NaN | ... | 71.097264 | NaN | 70.908257 | NaN | 71.490765 | NaN | 71.355191 | NaN | 70.643875 | NaN |
Swimming | NaN | 89.000000 | 72.750000 | 75.285714 | 72.904762 | 68.500000 | 73.769231 | 71.888889 | 83.400000 | 66.428571 | ... | NaN | 72.420455 | NaN | 72.387647 | NaN | 72.206736 | NaN | 72.547760 | NaN | 72.198046 |
Synchronized Swimming | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | ... | NaN | 55.880342 | NaN | 55.854701 | NaN | 56.017241 | NaN | 56.333333 | NaN | 55.618644 |
Table Tennis | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | ... | NaN | 64.872659 | NaN | 65.103846 | NaN | 65.250000 | NaN | 65.612069 | NaN | 64.688034 |
Taekwondo | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | ... | NaN | 68.331683 | NaN | 68.431452 | NaN | 68.096000 | NaN | 67.832031 | NaN | 67.411290 |
Tennis | NaN | NaN | 86.000000 | NaN | NaN | 84.500000 | 62.428571 | 70.666667 | NaN | NaN | ... | NaN | 69.788618 | NaN | 70.732000 | NaN | 71.208661 | NaN | 72.335664 | NaN | 72.104895 |
Trampolining | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | ... | NaN | 62.000000 | NaN | 60.437500 | NaN | 58.000000 | NaN | 58.133333 | NaN | 58.718750 |
Triathlon | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | ... | NaN | 62.969697 | NaN | 62.404040 | NaN | 61.954545 | NaN | 61.165138 | NaN | 60.752294 |
Tug-Of-War | NaN | NaN | 84.500000 | 86.285714 | 98.000000 | 101.333333 | 98.142857 | NaN | NaN | NaN | ... | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN |
Volleyball | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | ... | NaN | 80.730216 | NaN | 81.184397 | NaN | 79.943463 | NaN | 79.902439 | NaN | 80.293286 |
Water Polo | NaN | 95.000000 | 66.000000 | NaN | 84.666667 | 89.750000 | 90.500000 | 90.500000 | 95.000000 | NaN | ... | NaN | 83.709957 | NaN | 83.729412 | NaN | 85.542969 | NaN | 86.027237 | NaN | 85.449612 |
Weightlifting | 91.333333 | NaN | 85.000000 | 93.750000 | NaN | NaN | 79.857143 | 75.233645 | 78.523810 | 74.733333 | ... | NaN | 79.385501 | NaN | 79.787149 | NaN | 78.397233 | NaN | 78.840637 | NaN | 79.839216 |
Wrestling | 86.000000 | NaN | 64.500000 | 85.000000 | 77.051724 | 82.676471 | 77.269231 | 72.382353 | 71.666667 | 76.388889 | ... | NaN | 78.044728 | NaN | 76.684751 | NaN | 75.865889 | NaN | 75.854354 | NaN | 78.028902 |
56 rows × 35 columns
# Extract the rows for Season == Summer and Year >= 2000
summer = athletes.loc[athletes['Season'] == 'Summer',:]
summer2000 = summer.loc[summer['Year'] >= 2000,:]
summer2000.head()
ID | Name | Sex | Age | Height | Weight | Team | NOC | Games | Year | Season | City | Sport | Event | Medal | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
1 | 2 | A Lamusi | M | 23.0 | 170.0 | 60.0 | China | CHN | 2012 Summer | 2012 | Summer | London | Judo | Judo Men's Extra-Lightweight | NaN |
31 | 12 | Jyri Tapani Aalto | M | 31.0 | 172.0 | 70.0 | Finland | FIN | 2000 Summer | 2000 | Summer | Sydney | Badminton | Badminton Men's Singles | NaN |
33 | 13 | Minna Maarit Aalto | F | 34.0 | 159.0 | 55.5 | Finland | FIN | 2000 Summer | 2000 | Summer | Sydney | Sailing | Sailing Women's Windsurfer | NaN |
57 | 18 | Timo Antero Aaltonen | M | 31.0 | 189.0 | 130.0 | Finland | FIN | 2000 Summer | 2000 | Summer | Sydney | Athletics | Athletics Men's Shot Put | NaN |
79 | 21 | Ragnhild Margrethe Aamodt | F | 27.0 | 163.0 | NaN | Norway | NOR | 2008 Summer | 2008 | Summer | Beijing | Handball | Handball Women's Handball | Gold |
# Repeat the pivoting step on the summer2000 data
awsy = summer2000.pivot_table(index='Sport', columns='Year', values='Weight', aggfunc='mean')
# Remove rows that only contain NaN values
awsy = awsy.dropna(how='all')
awsy.round(1)
Year | 2000 | 2004 | 2008 | 2012 | 2016 |
---|---|---|---|---|---|
Sport | |||||
Archery | 70.2 | 70.4 | 72.7 | 71.8 | 72.2 |
Athletics | 69.7 | 69.9 | 69.4 | 68.9 | 67.4 |
Badminton | 67.5 | 68.1 | 67.9 | 68.0 | 69.0 |
Baseball | 85.5 | 88.0 | 88.2 | NaN | NaN |
Basketball | 86.6 | 86.9 | 87.2 | 87.4 | 87.9 |
Beach Volleyball | 78.7 | 79.5 | 79.9 | 79.5 | 78.6 |
Boxing | 66.1 | 66.1 | 66.4 | 67.2 | 66.6 |
Canoeing | 78.0 | 77.7 | 78.0 | 76.3 | 77.0 |
Cycling | 69.8 | 69.5 | 69.9 | 69.2 | 68.4 |
Diving | 59.7 | 60.6 | 60.5 | 59.8 | 60.6 |
Equestrianism | 67.3 | 68.3 | 67.8 | 67.7 | 67.9 |
Fencing | 72.8 | 72.4 | 70.4 | 69.7 | 71.2 |
Football | 70.1 | 69.1 | 69.8 | 68.1 | 68.4 |
Golf | NaN | NaN | NaN | NaN | 71.2 |
Gymnastics | 54.8 | 55.2 | 55.2 | 56.3 | 56.5 |
Handball | 80.6 | 82.3 | 81.6 | 82.2 | 83.3 |
Hockey | 69.3 | 68.9 | 68.6 | 69.0 | 68.8 |
Judo | 77.9 | 78.6 | 79.4 | 77.5 | 77.2 |
Modern Pentathlon | 66.2 | 66.7 | 66.2 | 66.2 | 66.3 |
Rhythmic Gymnastics | 46.6 | 49.4 | 50.9 | 51.6 | 50.4 |
Rowing | 80.7 | 80.7 | 80.8 | 80.8 | 79.9 |
Rugby Sevens | NaN | NaN | NaN | NaN | 78.9 |
Sailing | 76.4 | 73.0 | 73.3 | 74.1 | 71.3 |
Shooting | 73.0 | 74.4 | 74.7 | 72.7 | 73.2 |
Softball | 68.0 | 68.0 | 67.8 | NaN | NaN |
Swimming | 72.4 | 72.4 | 72.2 | 72.5 | 72.2 |
Synchronized Swimming | 55.9 | 55.9 | 56.0 | 56.3 | 55.6 |
Table Tennis | 64.9 | 65.1 | 65.2 | 65.6 | 64.7 |
Taekwondo | 68.3 | 68.4 | 68.1 | 67.8 | 67.4 |
Tennis | 69.8 | 70.7 | 71.2 | 72.3 | 72.1 |
Trampolining | 62.0 | 60.4 | 58.0 | 58.1 | 58.7 |
Triathlon | 63.0 | 62.4 | 62.0 | 61.2 | 60.8 |
Volleyball | 80.7 | 81.2 | 79.9 | 79.9 | 80.3 |
Water Polo | 83.7 | 83.7 | 85.5 | 86.0 | 85.4 |
Weightlifting | 79.4 | 79.8 | 78.4 | 78.8 | 79.8 |
Wrestling | 78.0 | 76.7 | 75.9 | 75.9 | 78.0 |
Aggregate on multiple functions and/or values#
# Repeat, but limit to summers of 2000-2016
awsy = summer2000.pivot_table(index='Sport', columns='Year', values=['Weight','Height'], aggfunc=['mean','max'])
# Remove rows that only contain NaN values
awsy = awsy.dropna(how='all')
awsy.round(1).head()
mean | max | |||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
Height | Weight | Height | Weight | |||||||||||||||||
Year | 2000 | 2004 | 2008 | 2012 | 2016 | 2000 | 2004 | 2008 | 2012 | 2016 | 2000 | 2004 | 2008 | 2012 | 2016 | 2000 | 2004 | 2008 | 2012 | 2016 |
Sport | ||||||||||||||||||||
Archery | 174.1 | 173.7 | 173.3 | 173.3 | 173.4 | 70.2 | 70.4 | 72.7 | 71.8 | 72.2 | 197.0 | 197.0 | 193.0 | 194.0 | 194.0 | 113.0 | 115.0 | 100.0 | 115.0 | 130.0 |
Athletics | 176.5 | 176.3 | 176.0 | 176.1 | 175.2 | 69.7 | 69.9 | 69.4 | 68.9 | 67.4 | 205.0 | 207.0 | 206.0 | 208.0 | 208.0 | 165.0 | 165.0 | 165.0 | 160.0 | 165.0 |
Badminton | 173.9 | 173.6 | 173.7 | 174.3 | 174.5 | 67.5 | 68.1 | 67.9 | 68.0 | 69.0 | 199.0 | 193.0 | 195.0 | 201.0 | 201.0 | 90.0 | 89.0 | 96.0 | 93.0 | 93.0 |
Baseball | 182.4 | 183.5 | 183.8 | NaN | NaN | 85.5 | 88.0 | 88.2 | NaN | NaN | 206.0 | 201.0 | 198.0 | NaN | NaN | 110.0 | 112.0 | 120.0 | NaN | NaN |
Basketball | 191.0 | 191.6 | 191.7 | 192.4 | 191.9 | 86.6 | 86.9 | 87.2 | 87.4 | 87.9 | 226.0 | 226.0 | 226.0 | 221.0 | 218.0 | 141.0 | 141.0 | 156.0 | 125.0 | 137.0 |
# Repeat, but add margins
awsy = summer2000.pivot_table(index='Sport', columns='Year', values=['Weight','Height'], aggfunc='max', margins=True)
# Remove rows that only contain NaN values
awsy = awsy.dropna(how='all')
awsy.round(1).head()
Height | Weight | |||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|
Year | 2000 | 2004 | 2008 | 2012 | 2016 | All | 2000 | 2004 | 2008 | 2012 | 2016 | All |
Sport | ||||||||||||
Archery | 197.0 | 197.0 | 193.0 | 194.0 | 194.0 | 197.0 | 113.0 | 115.0 | 100.0 | 115.0 | 130.0 | 130.0 |
Athletics | 205.0 | 207.0 | 206.0 | 208.0 | 208.0 | 208.0 | 165.0 | 165.0 | 165.0 | 160.0 | 165.0 | 165.0 |
Badminton | 199.0 | 193.0 | 195.0 | 201.0 | 201.0 | 201.0 | 90.0 | 89.0 | 96.0 | 93.0 | 93.0 | 96.0 |
Baseball | 206.0 | 201.0 | 198.0 | NaN | NaN | 206.0 | 110.0 | 112.0 | 120.0 | NaN | NaN | 120.0 |
Basketball | 226.0 | 226.0 | 226.0 | 221.0 | 218.0 | 226.0 | 141.0 | 141.0 | 156.0 | 125.0 | 137.0 | 156.0 |
Stack and unstack#
These operations switch between the groupby-format and the pivot_table-format.
# Groupby with two columns
athlete_weight_by_sport_groupby = athletes.groupby('Sport')[['Weight','Height']].mean()
athlete_weight_by_sport_groupby
Weight | Height | |
---|---|---|
Sport | ||
Aeronautics | NaN | NaN |
Alpine Skiing | 72.068110 | 173.489052 |
Alpinism | NaN | NaN |
Archery | 70.011135 | 173.203085 |
Art Competitions | 75.290909 | 174.644068 |
... | ... | ... |
Tug-Of-War | 95.615385 | 182.480000 |
Volleyball | 78.900214 | 186.994822 |
Water Polo | 84.566446 | 184.834648 |
Weightlifting | 78.726663 | 167.824801 |
Wrestling | 75.495570 | 172.358586 |
66 rows × 2 columns
# Unstack the result
athlete_weight_by_sport_groupby.unstack()
Sport
Weight Aeronautics NaN
Alpine Skiing 72.068110
Alpinism NaN
Archery 70.011135
Art Competitions 75.290909
...
Height Tug-Of-War 182.480000
Volleyball 186.994822
Water Polo 184.834648
Weightlifting 167.824801
Wrestling 172.358586
Length: 132, dtype: float64
Exercise#
Extract winter olympics.
Make yearly medal statistics for all countries using pivoting to count medals.
Remove all countries that have no winter olympic medals.
Extract the top 10 countries that have the most winter olympic medals in sum.
Use the noc_regions.csv to exchange the NOC codes with region names.
Plot the resulting 10 curves as proportions of medals per year.
Place the legend outside the plot
See also
Resources