Baby Names

Python for Data Analysis (3e) by Wes McKinney

Author

Sungkyun Cho

Published

October 31, 2024

Load packages
# numerical calculation & data frames
import numpy as np
import pandas as pd

# visualization
import matplotlib.pyplot as plt
import seaborn as sns
import seaborn.objects as so

# statistics
import statsmodels.api as sm

# pandas options
pd.set_option('mode.copy_on_write', True)  # pandas 2.0
pd.options.display.float_format = '{:.2f}'.format  # pd.reset_option('display.float_format')
pd.options.display.max_rows = 7  # max number of rows to display

# NumPy options
np.set_printoptions(precision = 2, suppress=True)  # suppress scientific notation

# For high resolution display
import matplotlib_inline
matplotlib_inline.backend_inline.set_matplotlib_formats("retina")

US Baby Names 1880–2010

Source: McKinney’s: 13. Data Analysis Examples

다음 데이터는 미국의 출생아 이름에 대한 데이터입니다. 링크

  • 2021년 업데이트된 버전으로 1880년부터 2021년까지의 데이터가 있으며,
  • 각 연도별로 남자아이와 여자아이의 이름별 출생아 수를 나타내고 있습니다.
names = pd.read_csv("data/babynames.csv")
names
          name sex  births  year
0         Mary   F    7065  1880
1         Anna   F    2604  1880
2         Emma   F    2003  1880
...        ...  ..     ...   ...
2052778  Zyian   M       5  2021
2052779  Zylar   M       5  2021
2052780    Zyn   M       5  2021

[2052781 rows x 4 columns]

1. 다음과 같이 년도와 성별에 따른 출생아 수의 합계를 구해보세요.

  • groupbysum을 사용하세요.
code
names_sex_year = names.groupby(["year", "sex"])["births"].sum().reset_index()
names_sex_year
     year sex   births
0    1880   F    90994
1    1880   M   110490
2    1881   F    91953
..    ...  ..      ...
281  2020   M  1718248
282  2021   F  1627098
283  2021   M  1734277

[284 rows x 3 columns]

2. 이를 이용해 다음과 같이 연도에 따른 출생아 수의 변화를 성별에 따라 그려보세요.

code
(
    so.Plot(names_sex_year, x='year', y='births', color="sex")
    .add(so.Line())
)

3. names 데이터프레임에 각 이름별 출생아 수의 비율을 나타내는 컬럼 prop을 추가하세요.

  • 예를 들어, 아래 결과 테이블 첫 행을 보면, 1880년 Mary라는 이름의 여자 출생아 수는 7065명인데, 이는 1880년에 태어난 총 여자 아이 중 7.764%를 차지합니다.
  • year, sex로 그룹핑을 한 후
  • 이 비율을 계산하는 함수를 세워서 apply method를 이용하여 prop 컬럼을 추가해 보세요.
code
def add_prop(group):
    group = group.assign(prop = lambda x: x.births / x.births.sum())
    return group

# 또는
def add_prop(group):
    group["prop"] = group["births"] / group["births"].sum()
    return group

names = names.groupby(["year", "sex"], group_keys=False).apply(add_prop)
names
          name sex  births  year  prop
0         Mary   F    7065  1880  0.08
1         Anna   F    2604  1880  0.03
2         Emma   F    2003  1880  0.02
...        ...  ..     ...   ...   ...
2052778  Zyian   M       5  2021  0.00
2052779  Zylar   M       5  2021  0.00
2052780    Zyn   M       5  2021  0.00

[2052781 rows x 5 columns]

4. 이제 names에서 각 연도에서 남녀별 인기있는 이름 1000개씩을 추립니다.

  • 즉, 1880년 인기있는 여자아이 1000개, 남자아이 1000개를 추리고, 1881년에도 마찬가지…
  • 인기있다는 것은 그 이름의 출생아 수가 많다는 의미입니다.
  • 3번과 마찬가지로, year, sex로 그룹핑을 한 후
  • grouped object에 sort_values method를 적용하여 상위 1000개를 추출하는 함수 세워 apply로 적용해 보세요.
code
def get_top1000(group):
    return group.sort_values("births", ascending=False)[:1000]

top1000 = names.groupby(["year", "sex"], group_keys=False).apply(
    get_top1000
)  # group_keys=False: 그룹핑 한 변수들을 인덱스로 사용하지 않음
top1000
            name sex  births  year  prop
0           Mary   F    7065  1880  0.08
1           Anna   F    2604  1880  0.03
2           Emma   F    2003  1880  0.02
...          ...  ..     ...   ...   ...
2039793   Ronnie   M     217  2021  0.00
2039792  Merrick   M     217  2021  0.00
2039791   Mayson   M     217  2021  0.00

[283876 rows x 5 columns]