%matplotlib inline
import pandas as pd
names1880 = pd.read_csv('/Users/yong27/study/pydata/pydata-book/ch02/names/yob1880.txt', names=['name', 'sex', 'births'])
names1880
name | sex | births | |
---|---|---|---|
0 | Mary | F | 7065 |
1 | Anna | F | 2604 |
2 | Emma | F | 2003 |
3 | Elizabeth | F | 1939 |
4 | Minnie | F | 1746 |
5 | Margaret | F | 1578 |
6 | Ida | F | 1472 |
7 | Alice | F | 1414 |
8 | Bertha | F | 1320 |
9 | Sarah | F | 1288 |
10 | Annie | F | 1258 |
11 | Clara | F | 1226 |
12 | Ella | F | 1156 |
13 | Florence | F | 1063 |
14 | Cora | F | 1045 |
15 | Martha | F | 1040 |
16 | Laura | F | 1012 |
17 | Nellie | F | 995 |
18 | Grace | F | 982 |
19 | Carrie | F | 949 |
20 | Maude | F | 858 |
21 | Mabel | F | 808 |
22 | Bessie | F | 794 |
23 | Jennie | F | 793 |
24 | Gertrude | F | 787 |
25 | Julia | F | 783 |
26 | Hattie | F | 769 |
27 | Edith | F | 768 |
28 | Mattie | F | 704 |
29 | Rose | F | 700 |
... | ... | ... | ... |
1970 | Philo | M | 5 |
1971 | Phineas | M | 5 |
1972 | Presley | M | 5 |
1973 | Ransom | M | 5 |
1974 | Reece | M | 5 |
1975 | Rene | M | 5 |
1976 | Roswell | M | 5 |
1977 | Rowland | M | 5 |
1978 | Sampson | M | 5 |
1979 | Samual | M | 5 |
1980 | Santos | M | 5 |
1981 | Schuyler | M | 5 |
1982 | Sheppard | M | 5 |
1983 | Spurgeon | M | 5 |
1984 | Starling | M | 5 |
1985 | Sylvanus | M | 5 |
1986 | Theadore | M | 5 |
1987 | Theophile | M | 5 |
1988 | Tilmon | M | 5 |
1989 | Tommy | M | 5 |
1990 | Unknown | M | 5 |
1991 | Vann | M | 5 |
1992 | Wes | M | 5 |
1993 | Winston | M | 5 |
1994 | Wood | M | 5 |
1995 | Woodie | M | 5 |
1996 | Worthy | M | 5 |
1997 | Wright | M | 5 |
1998 | York | M | 5 |
1999 | Zachariah | M | 5 |
2000 rows × 3 columns
1880년생 이름들이 잘 로드되었다 (상위 2000개 이름들만 제공함). 성별별로 몇명이나 있는지 계산해보자.
names1880.groupby('sex').births.sum()
sex F 90993 M 110493 Name: births, dtype: int64
1880년생뿐 아니라 모든 연도 출생자들을 다 로드해보자.
years = range(1880, 2011)
pieces = []
columns = ['name', 'sex', 'births']
for year in years:
path = '/Users/yong27/study/pydata/pydata-book/ch02/names/yob{}.txt'.format(year)
frame = pd.read_csv(path, names=columns)
frame['year'] = year
pieces.append(frame)
names = pd.concat(pieces, ignore_index=True)
names
name | sex | births | year | |
---|---|---|---|---|
0 | Mary | F | 7065 | 1880 |
1 | Anna | F | 2604 | 1880 |
2 | Emma | F | 2003 | 1880 |
3 | Elizabeth | F | 1939 | 1880 |
4 | Minnie | F | 1746 | 1880 |
5 | Margaret | F | 1578 | 1880 |
6 | Ida | F | 1472 | 1880 |
7 | Alice | F | 1414 | 1880 |
8 | Bertha | F | 1320 | 1880 |
9 | Sarah | F | 1288 | 1880 |
10 | Annie | F | 1258 | 1880 |
11 | Clara | F | 1226 | 1880 |
12 | Ella | F | 1156 | 1880 |
13 | Florence | F | 1063 | 1880 |
14 | Cora | F | 1045 | 1880 |
15 | Martha | F | 1040 | 1880 |
16 | Laura | F | 1012 | 1880 |
17 | Nellie | F | 995 | 1880 |
18 | Grace | F | 982 | 1880 |
19 | Carrie | F | 949 | 1880 |
20 | Maude | F | 858 | 1880 |
21 | Mabel | F | 808 | 1880 |
22 | Bessie | F | 794 | 1880 |
23 | Jennie | F | 793 | 1880 |
24 | Gertrude | F | 787 | 1880 |
25 | Julia | F | 783 | 1880 |
26 | Hattie | F | 769 | 1880 |
27 | Edith | F | 768 | 1880 |
28 | Mattie | F | 704 | 1880 |
29 | Rose | F | 700 | 1880 |
... | ... | ... | ... | ... |
1690754 | Zaviyon | M | 5 | 2010 |
1690755 | Zaybrien | M | 5 | 2010 |
1690756 | Zayshawn | M | 5 | 2010 |
1690757 | Zayyan | M | 5 | 2010 |
1690758 | Zeal | M | 5 | 2010 |
1690759 | Zealan | M | 5 | 2010 |
1690760 | Zecharia | M | 5 | 2010 |
1690761 | Zeferino | M | 5 | 2010 |
1690762 | Zekariah | M | 5 | 2010 |
1690763 | Zeki | M | 5 | 2010 |
1690764 | Zeriah | M | 5 | 2010 |
1690765 | Zeshan | M | 5 | 2010 |
1690766 | Zhyier | M | 5 | 2010 |
1690767 | Zildjian | M | 5 | 2010 |
1690768 | Zinn | M | 5 | 2010 |
1690769 | Zishan | M | 5 | 2010 |
1690770 | Ziven | M | 5 | 2010 |
1690771 | Zmari | M | 5 | 2010 |
1690772 | Zoren | M | 5 | 2010 |
1690773 | Zuhaib | M | 5 | 2010 |
1690774 | Zyeire | M | 5 | 2010 |
1690775 | Zygmunt | M | 5 | 2010 |
1690776 | Zykerion | M | 5 | 2010 |
1690777 | Zylar | M | 5 | 2010 |
1690778 | Zylin | M | 5 | 2010 |
1690779 | Zymaire | M | 5 | 2010 |
1690780 | Zyonne | M | 5 | 2010 |
1690781 | Zyquarius | M | 5 | 2010 |
1690782 | Zyran | M | 5 | 2010 |
1690783 | Zzyzx | M | 5 | 2010 |
1690784 rows × 4 columns
모든 연도의 데이터가 다 로드되어 names라는 하나의 Dataframe에 저장되었다. 총 1,690,784개의 레코드가 있다.
total_births = names.pivot_table('births', index='year', columns='sex', aggfunc=sum)
total_births
sex | F | M |
---|---|---|
year | ||
1880 | 90993 | 110493 |
1881 | 91955 | 100748 |
1882 | 107851 | 113687 |
1883 | 112322 | 104632 |
1884 | 129021 | 114445 |
1885 | 133056 | 107802 |
1886 | 144538 | 110785 |
1887 | 145983 | 101412 |
1888 | 178631 | 120857 |
1889 | 178369 | 110590 |
1890 | 190377 | 111026 |
1891 | 185486 | 101198 |
1892 | 212350 | 122038 |
1893 | 212908 | 112319 |
1894 | 222923 | 115775 |
1895 | 233632 | 117398 |
1896 | 237924 | 119575 |
1897 | 234199 | 112760 |
1898 | 258771 | 122703 |
1899 | 233022 | 106218 |
1900 | 299873 | 150554 |
1901 | 239351 | 106478 |
1902 | 264079 | 122660 |
1903 | 261976 | 119240 |
1904 | 275375 | 128129 |
1905 | 291641 | 132319 |
1906 | 295301 | 133159 |
1907 | 318558 | 146838 |
1908 | 334277 | 154339 |
1909 | 347191 | 163983 |
... | ... | ... |
1981 | 1666833 | 1789568 |
1982 | 1692036 | 1812642 |
1983 | 1669486 | 1790670 |
1984 | 1682396 | 1802735 |
1985 | 1719450 | 1846162 |
1986 | 1714053 | 1839442 |
1987 | 1737508 | 1865113 |
1988 | 1779112 | 1911858 |
1989 | 1843057 | 1999840 |
1990 | 1897256 | 2052070 |
1991 | 1874110 | 2019018 |
1992 | 1842818 | 1995760 |
1993 | 1807795 | 1959712 |
1994 | 1784407 | 1930363 |
1995 | 1757240 | 1902100 |
1996 | 1751681 | 1892700 |
1997 | 1739331 | 1883571 |
1998 | 1765390 | 1909676 |
1999 | 1772139 | 1918267 |
2000 | 1813960 | 1961702 |
2001 | 1798284 | 1940498 |
2002 | 1794358 | 1938941 |
2003 | 1824406 | 1972439 |
2004 | 1833005 | 1981557 |
2005 | 1843890 | 1993285 |
2006 | 1896468 | 2050234 |
2007 | 1916888 | 2069242 |
2008 | 1883645 | 2032310 |
2009 | 1827643 | 1973359 |
2010 | 1759010 | 1898382 |
131 rows × 2 columns
Dataframe.pivot_table 메쏘드는 테이블내 두 컬럼을 결합한다. 이 데이터를 가지고, 매년 남녀 출생수(births)를 차트로 표시해보자.
total_births.plot(title='Total births by sex and year')
<matplotlib.axes._subplots.AxesSubplot at 0x108097c18>
매년 남녀 출생수 현황을 한눈에 알 수 있다. 1930년전에는 여자가 많았는데, 그 이후에 남자가 많이지는 점이 이채롭다.
이제, 각 레코드에 "prop" 컬럼을 만들고, 해당 이름의 빈도를 추가해보자.
def add_prop(group):
#births = group.births.astype(float)
group['prop'] = group.births / group.births.sum()
return group
names = names.groupby(['year', 'sex']).apply(add_prop)
names
name | sex | births | year | prop | |
---|---|---|---|---|---|
0 | Mary | F | 7065 | 1880 | 0.077643 |
1 | Anna | F | 2604 | 1880 | 0.028618 |
2 | Emma | F | 2003 | 1880 | 0.022013 |
3 | Elizabeth | F | 1939 | 1880 | 0.021309 |
4 | Minnie | F | 1746 | 1880 | 0.019188 |
5 | Margaret | F | 1578 | 1880 | 0.017342 |
6 | Ida | F | 1472 | 1880 | 0.016177 |
7 | Alice | F | 1414 | 1880 | 0.015540 |
8 | Bertha | F | 1320 | 1880 | 0.014507 |
9 | Sarah | F | 1288 | 1880 | 0.014155 |
10 | Annie | F | 1258 | 1880 | 0.013825 |
11 | Clara | F | 1226 | 1880 | 0.013474 |
12 | Ella | F | 1156 | 1880 | 0.012704 |
13 | Florence | F | 1063 | 1880 | 0.011682 |
14 | Cora | F | 1045 | 1880 | 0.011484 |
15 | Martha | F | 1040 | 1880 | 0.011429 |
16 | Laura | F | 1012 | 1880 | 0.011122 |
17 | Nellie | F | 995 | 1880 | 0.010935 |
18 | Grace | F | 982 | 1880 | 0.010792 |
19 | Carrie | F | 949 | 1880 | 0.010429 |
20 | Maude | F | 858 | 1880 | 0.009429 |
21 | Mabel | F | 808 | 1880 | 0.008880 |
22 | Bessie | F | 794 | 1880 | 0.008726 |
23 | Jennie | F | 793 | 1880 | 0.008715 |
24 | Gertrude | F | 787 | 1880 | 0.008649 |
25 | Julia | F | 783 | 1880 | 0.008605 |
26 | Hattie | F | 769 | 1880 | 0.008451 |
27 | Edith | F | 768 | 1880 | 0.008440 |
28 | Mattie | F | 704 | 1880 | 0.007737 |
29 | Rose | F | 700 | 1880 | 0.007693 |
... | ... | ... | ... | ... | ... |
1690754 | Zaviyon | M | 5 | 2010 | 0.000003 |
1690755 | Zaybrien | M | 5 | 2010 | 0.000003 |
1690756 | Zayshawn | M | 5 | 2010 | 0.000003 |
1690757 | Zayyan | M | 5 | 2010 | 0.000003 |
1690758 | Zeal | M | 5 | 2010 | 0.000003 |
1690759 | Zealan | M | 5 | 2010 | 0.000003 |
1690760 | Zecharia | M | 5 | 2010 | 0.000003 |
1690761 | Zeferino | M | 5 | 2010 | 0.000003 |
1690762 | Zekariah | M | 5 | 2010 | 0.000003 |
1690763 | Zeki | M | 5 | 2010 | 0.000003 |
1690764 | Zeriah | M | 5 | 2010 | 0.000003 |
1690765 | Zeshan | M | 5 | 2010 | 0.000003 |
1690766 | Zhyier | M | 5 | 2010 | 0.000003 |
1690767 | Zildjian | M | 5 | 2010 | 0.000003 |
1690768 | Zinn | M | 5 | 2010 | 0.000003 |
1690769 | Zishan | M | 5 | 2010 | 0.000003 |
1690770 | Ziven | M | 5 | 2010 | 0.000003 |
1690771 | Zmari | M | 5 | 2010 | 0.000003 |
1690772 | Zoren | M | 5 | 2010 | 0.000003 |
1690773 | Zuhaib | M | 5 | 2010 | 0.000003 |
1690774 | Zyeire | M | 5 | 2010 | 0.000003 |
1690775 | Zygmunt | M | 5 | 2010 | 0.000003 |
1690776 | Zykerion | M | 5 | 2010 | 0.000003 |
1690777 | Zylar | M | 5 | 2010 | 0.000003 |
1690778 | Zylin | M | 5 | 2010 | 0.000003 |
1690779 | Zymaire | M | 5 | 2010 | 0.000003 |
1690780 | Zyonne | M | 5 | 2010 | 0.000003 |
1690781 | Zyquarius | M | 5 | 2010 | 0.000003 |
1690782 | Zyran | M | 5 | 2010 | 0.000003 |
1690783 | Zzyzx | M | 5 | 2010 | 0.000003 |
1690784 rows × 5 columns
해당 연도, 성별을 그룹으로 하고, 그 그룹에서의 이름 빈도가 추가되었다. 이 빈도가 정확하게 계산되었는지 궁금하다. 한번 확인해보자.
import numpy as np
np.allclose(names.groupby(['year', 'sex']).prop.sum(), 1)
True
오케이. 이제부터 매년, 각 성별별로 특정 이름의 빈도 변화를 살펴보자. 매년, 각 성별별(그룹별)로 데이터수가 다르니, 그룹별 top1000만 쓰기로 하자.
def get_top1000(group):
return group.sort_values(by='births', ascending=False)[:1000]
grouped = names.groupby(['year', 'sex'])
top1000 = grouped.apply(get_top1000)
top1000
name | sex | births | year | prop | |||
---|---|---|---|---|---|---|---|
year | sex | ||||||
1880 | F | 0 | Mary | F | 7065 | 1880 | 0.077643 |
1 | Anna | F | 2604 | 1880 | 0.028618 | ||
2 | Emma | F | 2003 | 1880 | 0.022013 | ||
3 | Elizabeth | F | 1939 | 1880 | 0.021309 | ||
4 | Minnie | F | 1746 | 1880 | 0.019188 | ||
5 | Margaret | F | 1578 | 1880 | 0.017342 | ||
6 | Ida | F | 1472 | 1880 | 0.016177 | ||
7 | Alice | F | 1414 | 1880 | 0.015540 | ||
8 | Bertha | F | 1320 | 1880 | 0.014507 | ||
9 | Sarah | F | 1288 | 1880 | 0.014155 | ||
10 | Annie | F | 1258 | 1880 | 0.013825 | ||
11 | Clara | F | 1226 | 1880 | 0.013474 | ||
12 | Ella | F | 1156 | 1880 | 0.012704 | ||
13 | Florence | F | 1063 | 1880 | 0.011682 | ||
14 | Cora | F | 1045 | 1880 | 0.011484 | ||
15 | Martha | F | 1040 | 1880 | 0.011429 | ||
16 | Laura | F | 1012 | 1880 | 0.011122 | ||
17 | Nellie | F | 995 | 1880 | 0.010935 | ||
18 | Grace | F | 982 | 1880 | 0.010792 | ||
19 | Carrie | F | 949 | 1880 | 0.010429 | ||
20 | Maude | F | 858 | 1880 | 0.009429 | ||
21 | Mabel | F | 808 | 1880 | 0.008880 | ||
22 | Bessie | F | 794 | 1880 | 0.008726 | ||
23 | Jennie | F | 793 | 1880 | 0.008715 | ||
24 | Gertrude | F | 787 | 1880 | 0.008649 | ||
25 | Julia | F | 783 | 1880 | 0.008605 | ||
26 | Hattie | F | 769 | 1880 | 0.008451 | ||
27 | Edith | F | 768 | 1880 | 0.008440 | ||
28 | Mattie | F | 704 | 1880 | 0.007737 | ||
29 | Rose | F | 700 | 1880 | 0.007693 | ||
... | ... | ... | ... | ... | ... | ... | ... |
2010 | M | 1677617 | Yair | M | 201 | 2010 | 0.000106 |
1677616 | Talan | M | 201 | 2010 | 0.000106 | ||
1677614 | Keyon | M | 201 | 2010 | 0.000106 | ||
1677613 | Kael | M | 201 | 2010 | 0.000106 | ||
1677618 | Demarion | M | 200 | 2010 | 0.000105 | ||
1677619 | Gibson | M | 200 | 2010 | 0.000105 | ||
1677620 | Reagan | M | 200 | 2010 | 0.000105 | ||
1677621 | Cristofer | M | 199 | 2010 | 0.000105 | ||
1677622 | Daylen | M | 199 | 2010 | 0.000105 | ||
1677623 | Jordon | M | 199 | 2010 | 0.000105 | ||
1677624 | Dashawn | M | 198 | 2010 | 0.000104 | ||
1677625 | Masen | M | 198 | 2010 | 0.000104 | ||
1677629 | Rowen | M | 197 | 2010 | 0.000104 | ||
1677631 | Yousef | M | 197 | 2010 | 0.000104 | ||
1677630 | Thaddeus | M | 197 | 2010 | 0.000104 | ||
1677628 | Kadin | M | 197 | 2010 | 0.000104 | ||
1677627 | Dillan | M | 197 | 2010 | 0.000104 | ||
1677626 | Clarence | M | 197 | 2010 | 0.000104 | ||
1677634 | Slade | M | 196 | 2010 | 0.000103 | ||
1677632 | Clinton | M | 196 | 2010 | 0.000103 | ||
1677633 | Sheldon | M | 196 | 2010 | 0.000103 | ||
1677636 | Keshawn | M | 195 | 2010 | 0.000103 | ||
1677637 | Menachem | M | 195 | 2010 | 0.000103 | ||
1677635 | Joziah | M | 195 | 2010 | 0.000103 | ||
1677638 | Bailey | M | 194 | 2010 | 0.000102 | ||
1677639 | Camilo | M | 194 | 2010 | 0.000102 | ||
1677640 | Destin | M | 194 | 2010 | 0.000102 | ||
1677641 | Jaquan | M | 194 | 2010 | 0.000102 | ||
1677642 | Jaydan | M | 194 | 2010 | 0.000102 | ||
1677645 | Maxton | M | 193 | 2010 | 0.000102 |
261877 rows × 5 columns
boys = top1000[top1000.sex == 'M']
girls = top1000[top1000.sex == 'F']
그리고, top1000을 피벗테이블로 펼쳐보자.
total_births = top1000.pivot_table('births', index='year', columns='name', aggfunc=sum)
total_births
name | Aaden | Aaliyah | Aarav | Aaron | Aarush | Ab | Abagail | Abb | Abbey | Abbie | ... | Zoa | Zoe | Zoey | Zoie | Zola | Zollie | Zona | Zora | Zula | Zuri |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
year | |||||||||||||||||||||
1880 | NaN | NaN | NaN | 102.0 | NaN | NaN | NaN | NaN | NaN | 71.0 | ... | 8.0 | 23.0 | NaN | NaN | 7.0 | NaN | 8.0 | 28.0 | 27.0 | NaN |
1881 | NaN | NaN | NaN | 94.0 | NaN | NaN | NaN | NaN | NaN | 81.0 | ... | NaN | 22.0 | NaN | NaN | 10.0 | NaN | 9.0 | 21.0 | 27.0 | NaN |
1882 | NaN | NaN | NaN | 85.0 | NaN | NaN | NaN | NaN | NaN | 80.0 | ... | 8.0 | 25.0 | NaN | NaN | 9.0 | NaN | 17.0 | 32.0 | 21.0 | NaN |
1883 | NaN | NaN | NaN | 105.0 | NaN | NaN | NaN | NaN | NaN | 79.0 | ... | NaN | 23.0 | NaN | NaN | 10.0 | NaN | 11.0 | 35.0 | 25.0 | NaN |
1884 | NaN | NaN | NaN | 97.0 | NaN | NaN | NaN | NaN | NaN | 98.0 | ... | 13.0 | 31.0 | NaN | NaN | 14.0 | 6.0 | 8.0 | 58.0 | 27.0 | NaN |
1885 | NaN | NaN | NaN | 88.0 | NaN | 6.0 | NaN | NaN | NaN | 88.0 | ... | 6.0 | 27.0 | NaN | NaN | 12.0 | 6.0 | 14.0 | 48.0 | 38.0 | NaN |
1886 | NaN | NaN | NaN | 86.0 | NaN | NaN | NaN | NaN | NaN | 84.0 | ... | 13.0 | 25.0 | NaN | NaN | 8.0 | NaN | 20.0 | 52.0 | 43.0 | NaN |
1887 | NaN | NaN | NaN | 78.0 | NaN | NaN | NaN | NaN | NaN | 104.0 | ... | 9.0 | 34.0 | NaN | NaN | 23.0 | NaN | 28.0 | 46.0 | 33.0 | NaN |
1888 | NaN | NaN | NaN | 90.0 | NaN | NaN | NaN | NaN | NaN | 137.0 | ... | 11.0 | 42.0 | NaN | NaN | 23.0 | 7.0 | 30.0 | 42.0 | 45.0 | NaN |
1889 | NaN | NaN | NaN | 85.0 | NaN | NaN | NaN | NaN | NaN | 107.0 | ... | 14.0 | 29.0 | NaN | NaN | 22.0 | NaN | 29.0 | 53.0 | 55.0 | NaN |
1890 | NaN | NaN | NaN | 96.0 | NaN | NaN | NaN | 6.0 | NaN | 140.0 | ... | NaN | 42.0 | NaN | NaN | 32.0 | 7.0 | 27.0 | 60.0 | 65.0 | NaN |
1891 | NaN | NaN | NaN | 69.0 | NaN | NaN | NaN | NaN | NaN | 124.0 | ... | NaN | 34.0 | NaN | NaN | 29.0 | 6.0 | 14.0 | 52.0 | 45.0 | NaN |
1892 | NaN | NaN | NaN | 95.0 | NaN | NaN | NaN | NaN | NaN | 119.0 | ... | NaN | 34.0 | NaN | NaN | 27.0 | NaN | 25.0 | 66.0 | 53.0 | NaN |
1893 | NaN | NaN | NaN | 81.0 | NaN | NaN | NaN | NaN | NaN | 115.0 | ... | NaN | 23.0 | NaN | NaN | 34.0 | 6.0 | 15.0 | 67.0 | 70.0 | NaN |
1894 | NaN | NaN | NaN | 79.0 | NaN | NaN | NaN | NaN | NaN | 118.0 | ... | NaN | 28.0 | NaN | NaN | 51.0 | NaN | 23.0 | 66.0 | 64.0 | NaN |
1895 | NaN | NaN | NaN | 94.0 | NaN | NaN | NaN | NaN | NaN | 92.0 | ... | NaN | 34.0 | NaN | NaN | 60.0 | 11.0 | 38.0 | 55.0 | 55.0 | NaN |
1896 | NaN | NaN | NaN | 69.0 | NaN | NaN | NaN | NaN | NaN | 121.0 | ... | NaN | 36.0 | NaN | NaN | 47.0 | NaN | 38.0 | 72.0 | 65.0 | NaN |
1897 | NaN | NaN | NaN | 87.0 | NaN | NaN | NaN | NaN | NaN | 97.0 | ... | NaN | 35.0 | NaN | NaN | 51.0 | NaN | 28.0 | 67.0 | 79.0 | NaN |
1898 | NaN | NaN | NaN | 89.0 | NaN | NaN | NaN | NaN | NaN | 120.0 | ... | NaN | 30.0 | NaN | NaN | 62.0 | NaN | 28.0 | 65.0 | 83.0 | NaN |
1899 | NaN | NaN | NaN | 71.0 | NaN | NaN | NaN | NaN | NaN | 87.0 | ... | NaN | 27.0 | NaN | NaN | 49.0 | 6.0 | 31.0 | 56.0 | 60.0 | NaN |
1900 | NaN | NaN | NaN | 104.0 | NaN | NaN | NaN | NaN | NaN | 112.0 | ... | NaN | 26.0 | NaN | NaN | 48.0 | 9.0 | 44.0 | 99.0 | 71.0 | NaN |
1901 | NaN | NaN | NaN | 80.0 | NaN | NaN | NaN | NaN | NaN | 87.0 | ... | NaN | 26.0 | NaN | NaN | 56.0 | NaN | 31.0 | 58.0 | 57.0 | NaN |
1902 | NaN | NaN | NaN | 78.0 | NaN | NaN | NaN | NaN | NaN | 91.0 | ... | NaN | 34.0 | NaN | NaN | 58.0 | NaN | 23.0 | 58.0 | 66.0 | NaN |
1903 | NaN | NaN | NaN | 93.0 | NaN | NaN | NaN | NaN | NaN | 91.0 | ... | NaN | 19.0 | NaN | NaN | 64.0 | NaN | 41.0 | 83.0 | 74.0 | NaN |
1904 | NaN | NaN | NaN | 117.0 | NaN | NaN | NaN | NaN | NaN | 80.0 | ... | NaN | 27.0 | NaN | NaN | 46.0 | NaN | 35.0 | 54.0 | 74.0 | NaN |
1905 | NaN | NaN | NaN | 96.0 | NaN | NaN | NaN | NaN | NaN | 73.0 | ... | NaN | 24.0 | NaN | NaN | 66.0 | 8.0 | 24.0 | 55.0 | 61.0 | NaN |
1906 | NaN | NaN | NaN | 96.0 | NaN | NaN | NaN | NaN | NaN | 72.0 | ... | NaN | 19.0 | NaN | NaN | 59.0 | NaN | 37.0 | 64.0 | 58.0 | NaN |
1907 | NaN | NaN | NaN | 130.0 | NaN | NaN | NaN | NaN | NaN | 79.0 | ... | NaN | 19.0 | NaN | NaN | 53.0 | 11.0 | 39.0 | 92.0 | 72.0 | NaN |
1908 | NaN | NaN | NaN | 114.0 | NaN | NaN | NaN | NaN | NaN | 84.0 | ... | NaN | 23.0 | NaN | NaN | 70.0 | NaN | 31.0 | 59.0 | 53.0 | NaN |
1909 | NaN | NaN | NaN | 142.0 | NaN | NaN | NaN | NaN | NaN | 57.0 | ... | NaN | 22.0 | NaN | NaN | 59.0 | NaN | 39.0 | 57.0 | 76.0 | NaN |
... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... |
1981 | NaN | NaN | NaN | 14832.0 | NaN | NaN | NaN | NaN | 383.0 | 292.0 | ... | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN |
1982 | NaN | NaN | NaN | 14538.0 | NaN | NaN | NaN | NaN | 372.0 | 275.0 | ... | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN |
1983 | NaN | NaN | NaN | 14627.0 | NaN | NaN | NaN | NaN | 419.0 | 223.0 | ... | NaN | 174.0 | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN |
1984 | NaN | NaN | NaN | 13387.0 | NaN | NaN | NaN | NaN | 357.0 | 249.0 | ... | NaN | 200.0 | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN |
1985 | NaN | NaN | NaN | 13123.0 | NaN | NaN | NaN | NaN | 314.0 | 233.0 | ... | NaN | 193.0 | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN |
1986 | NaN | NaN | NaN | 12685.0 | NaN | NaN | NaN | NaN | 369.0 | 228.0 | ... | NaN | 213.0 | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN |
1987 | NaN | NaN | NaN | 12676.0 | NaN | NaN | NaN | NaN | 327.0 | 228.0 | ... | NaN | 248.0 | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN |
1988 | NaN | NaN | NaN | 14393.0 | NaN | NaN | NaN | NaN | 404.0 | 226.0 | ... | NaN | 238.0 | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN |
1989 | NaN | NaN | NaN | 15312.0 | NaN | NaN | NaN | NaN | 470.0 | 265.0 | ... | NaN | 376.0 | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN |
1990 | NaN | NaN | NaN | 14545.0 | NaN | NaN | NaN | NaN | 507.0 | 311.0 | ... | NaN | 478.0 | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN |
1991 | NaN | NaN | NaN | 14240.0 | NaN | NaN | NaN | NaN | 451.0 | 278.0 | ... | NaN | 722.0 | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN |
1992 | NaN | NaN | NaN | 14494.0 | NaN | NaN | NaN | NaN | 430.0 | 260.0 | ... | NaN | 978.0 | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN |
1993 | NaN | NaN | NaN | 13819.0 | NaN | NaN | NaN | NaN | 503.0 | 291.0 | ... | NaN | 1194.0 | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN |
1994 | NaN | 1451.0 | NaN | 14379.0 | NaN | NaN | NaN | NaN | 597.0 | 351.0 | ... | NaN | 1332.0 | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN |
1995 | NaN | 1254.0 | NaN | 13277.0 | NaN | NaN | NaN | NaN | 549.0 | 351.0 | ... | NaN | 1726.0 | 219.0 | NaN | NaN | NaN | NaN | NaN | NaN | NaN |
1996 | NaN | 831.0 | NaN | 11956.0 | NaN | NaN | NaN | NaN | 552.0 | 349.0 | ... | NaN | 2063.0 | 339.0 | NaN | NaN | NaN | NaN | NaN | NaN | NaN |
1997 | NaN | 1737.0 | NaN | 11156.0 | NaN | NaN | NaN | NaN | 645.0 | 386.0 | ... | NaN | 2363.0 | 407.0 | NaN | NaN | NaN | NaN | NaN | NaN | NaN |
1998 | NaN | 1399.0 | NaN | 10539.0 | NaN | NaN | NaN | NaN | 661.0 | 398.0 | ... | NaN | 2690.0 | 478.0 | 225.0 | NaN | NaN | NaN | NaN | NaN | NaN |
1999 | NaN | 1088.0 | NaN | 9846.0 | NaN | NaN | 211.0 | NaN | 710.0 | 430.0 | ... | NaN | 3238.0 | 561.0 | 257.0 | NaN | NaN | NaN | NaN | NaN | NaN |
2000 | NaN | 1494.0 | NaN | 9548.0 | NaN | NaN | 222.0 | NaN | 660.0 | 432.0 | ... | NaN | 3783.0 | 691.0 | 320.0 | NaN | NaN | NaN | NaN | NaN | NaN |
2001 | NaN | 3351.0 | NaN | 9529.0 | NaN | NaN | 244.0 | NaN | 687.0 | 526.0 | ... | NaN | 4642.0 | 822.0 | 439.0 | NaN | NaN | NaN | NaN | NaN | NaN |
2002 | NaN | 4775.0 | NaN | 8993.0 | NaN | NaN | 256.0 | NaN | 600.0 | 514.0 | ... | NaN | 4883.0 | 1182.0 | 438.0 | NaN | NaN | NaN | NaN | NaN | NaN |
2003 | NaN | 3670.0 | NaN | 8851.0 | NaN | NaN | 276.0 | NaN | 625.0 | 536.0 | ... | NaN | 5080.0 | 1465.0 | 448.0 | NaN | NaN | NaN | NaN | NaN | NaN |
2004 | NaN | 3482.0 | NaN | 8381.0 | NaN | NaN | 258.0 | NaN | 504.0 | 500.0 | ... | NaN | 5359.0 | 1621.0 | 515.0 | NaN | NaN | NaN | NaN | NaN | NaN |
2005 | NaN | 3452.0 | NaN | 7796.0 | NaN | NaN | 287.0 | NaN | 451.0 | 445.0 | ... | NaN | 4953.0 | 2266.0 | 502.0 | NaN | NaN | NaN | NaN | NaN | NaN |
2006 | NaN | 3737.0 | NaN | 8279.0 | NaN | NaN | 297.0 | NaN | 404.0 | 440.0 | ... | NaN | 5145.0 | 2839.0 | 530.0 | NaN | NaN | NaN | NaN | NaN | NaN |
2007 | NaN | 3941.0 | NaN | 8914.0 | NaN | NaN | 313.0 | NaN | 349.0 | 468.0 | ... | NaN | 4925.0 | 3028.0 | 526.0 | NaN | NaN | NaN | NaN | NaN | NaN |
2008 | 955.0 | 4028.0 | 219.0 | 8511.0 | NaN | NaN | 317.0 | NaN | 344.0 | 400.0 | ... | NaN | 4764.0 | 3438.0 | 492.0 | NaN | NaN | NaN | NaN | NaN | NaN |
2009 | 1265.0 | 4352.0 | 270.0 | 7936.0 | NaN | NaN | 296.0 | NaN | 307.0 | 369.0 | ... | NaN | 5120.0 | 3981.0 | 496.0 | NaN | NaN | NaN | NaN | NaN | NaN |
2010 | 448.0 | 4628.0 | 438.0 | 7374.0 | 226.0 | NaN | 277.0 | NaN | 295.0 | 324.0 | ... | NaN | 6200.0 | 5164.0 | 504.0 | NaN | NaN | NaN | NaN | NaN | 258.0 |
131 rows × 6868 columns
이름이 너무 많으니, 관심있는 이름 John, Harry, Mary, Marilyn만 확인해보자.
subset = total_births[['John', 'Harry', 'Mary', 'Marilyn']]
이 4명을 차트로 표시해보면,
subset.plot(subplots=True, figsize=(12, 10), grid=False, title='Number of births per year')
array([<matplotlib.axes._subplots.AxesSubplot object at 0x10bce0a20>, <matplotlib.axes._subplots.AxesSubplot object at 0x10c1cccf8>, <matplotlib.axes._subplots.AxesSubplot object at 0x10beb8f28>, <matplotlib.axes._subplots.AxesSubplot object at 0x10bef54e0>], dtype=object)
각 이름별로 매년 어떻게 변화하는지 한눈에 확인이 가능하다.
위 차트의 설명 가운데 하나는 부모들이 점점 일반적인 이름을 쓰지 않기 때문일 수 있다. 정말 그러한지 확인해보자.
table = top1000.pivot_table('prop', index='year', columns='sex', aggfunc=sum)
table
sex | F | M |
---|---|---|
year | ||
1880 | 1.000000 | 0.997375 |
1881 | 1.000000 | 1.000000 |
1882 | 0.998702 | 0.995646 |
1883 | 0.997596 | 0.998566 |
1884 | 0.993156 | 0.994539 |
1885 | 0.992251 | 0.995501 |
1886 | 0.989504 | 0.995035 |
1887 | 0.988279 | 0.996697 |
1888 | 0.984241 | 0.992429 |
1889 | 0.984061 | 0.994981 |
1890 | 0.982566 | 0.992749 |
1891 | 0.982177 | 0.993725 |
1892 | 0.979746 | 0.988815 |
1893 | 0.980001 | 0.991720 |
1894 | 0.978571 | 0.989048 |
1895 | 0.975479 | 0.989071 |
1896 | 0.975660 | 0.988041 |
1897 | 0.976558 | 0.989349 |
1898 | 0.972806 | 0.987197 |
1899 | 0.975170 | 0.990115 |
1900 | 0.967760 | 0.979702 |
1901 | 0.972304 | 0.989603 |
1902 | 0.970467 | 0.985749 |
1903 | 0.969490 | 0.986020 |
1904 | 0.968142 | 0.982502 |
1905 | 0.967038 | 0.981650 |
1906 | 0.967535 | 0.981759 |
1907 | 0.964942 | 0.976975 |
1908 | 0.964500 | 0.976409 |
1909 | 0.962744 | 0.973412 |
... | ... | ... |
1981 | 0.867232 | 0.944762 |
1982 | 0.868208 | 0.944435 |
1983 | 0.871602 | 0.945170 |
1984 | 0.870201 | 0.944705 |
1985 | 0.866046 | 0.942412 |
1986 | 0.862619 | 0.939833 |
1987 | 0.858719 | 0.937574 |
1988 | 0.852520 | 0.934236 |
1989 | 0.846535 | 0.928314 |
1990 | 0.840591 | 0.926585 |
1991 | 0.835156 | 0.923316 |
1992 | 0.829654 | 0.919513 |
1993 | 0.826035 | 0.915127 |
1994 | 0.823227 | 0.911285 |
1995 | 0.821738 | 0.909356 |
1996 | 0.817149 | 0.905296 |
1997 | 0.811416 | 0.901020 |
1998 | 0.805665 | 0.896381 |
1999 | 0.799804 | 0.892714 |
2000 | 0.791455 | 0.887008 |
2001 | 0.784125 | 0.882799 |
2002 | 0.780403 | 0.879775 |
2003 | 0.774850 | 0.876747 |
2004 | 0.767291 | 0.870077 |
2005 | 0.762426 | 0.866514 |
2006 | 0.753153 | 0.860368 |
2007 | 0.745959 | 0.855159 |
2008 | 0.740933 | 0.850003 |
2009 | 0.737290 | 0.845256 |
2010 | 0.736780 | 0.843156 |
131 rows × 2 columns
table.plot(title='Sum of table1000.prop by year and sex', yticks=np.linspace(0, 1.2, 13), xticks=range(1880, 2020, 10))
<matplotlib.axes._subplots.AxesSubplot at 0x10c7dc1d0>
그룹별 1000개 레코드의 이름빈도의 합계가 시간이 지날수록 1에서 멀어지는 걸 보아, 다양성이 증가하고 있음을 유추할 수 있다.
또 다른 계산방법으로, 이름빈도로 정렬했을 때, 50%에 도달할 때, 몇명이 있는지 확인할 수 있다. 많을수록 다양하다고 유추할 수 있다. 예를 들어 2010년 출생 남자들은,
df = boys[boys.year == 2010]
df
name | sex | births | year | prop | |||
---|---|---|---|---|---|---|---|
year | sex | ||||||
2010 | M | 1676644 | Jacob | M | 21875 | 2010 | 0.011523 |
1676645 | Ethan | M | 17866 | 2010 | 0.009411 | ||
1676646 | Michael | M | 17133 | 2010 | 0.009025 | ||
1676647 | Jayden | M | 17030 | 2010 | 0.008971 | ||
1676648 | William | M | 16870 | 2010 | 0.008887 | ||
1676649 | Alexander | M | 16634 | 2010 | 0.008762 | ||
1676650 | Noah | M | 16281 | 2010 | 0.008576 | ||
1676651 | Daniel | M | 15679 | 2010 | 0.008259 | ||
1676652 | Aiden | M | 15403 | 2010 | 0.008114 | ||
1676653 | Anthony | M | 15364 | 2010 | 0.008093 | ||
1676654 | Joshua | M | 15238 | 2010 | 0.008027 | ||
1676655 | Mason | M | 14728 | 2010 | 0.007758 | ||
1676656 | Christopher | M | 14135 | 2010 | 0.007446 | ||
1676657 | Andrew | M | 14093 | 2010 | 0.007424 | ||
1676658 | David | M | 14042 | 2010 | 0.007397 | ||
1676659 | Matthew | M | 13954 | 2010 | 0.007350 | ||
1676660 | Logan | M | 13943 | 2010 | 0.007345 | ||
1676661 | Elijah | M | 13735 | 2010 | 0.007235 | ||
1676662 | James | M | 13714 | 2010 | 0.007224 | ||
1676663 | Joseph | M | 13657 | 2010 | 0.007194 | ||
1676664 | Gabriel | M | 12722 | 2010 | 0.006701 | ||
1676665 | Benjamin | M | 12280 | 2010 | 0.006469 | ||
1676666 | Ryan | M | 11886 | 2010 | 0.006261 | ||
1676667 | Samuel | M | 11776 | 2010 | 0.006203 | ||
1676668 | Jackson | M | 11693 | 2010 | 0.006159 | ||
1676669 | John | M | 11424 | 2010 | 0.006018 | ||
1676670 | Nathan | M | 11269 | 2010 | 0.005936 | ||
1676671 | Jonathan | M | 11028 | 2010 | 0.005809 | ||
1676672 | Christian | M | 10965 | 2010 | 0.005776 | ||
1676673 | Liam | M | 10852 | 2010 | 0.005716 | ||
... | ... | ... | ... | ... | ... | ||
... | Yair | M | 201 | 2010 | 0.000106 | ||
1677617 | Talan | M | 201 | 2010 | 0.000106 | ||
1677616 | Keyon | M | 201 | 2010 | 0.000106 | ||
1677614 | Kael | M | 201 | 2010 | 0.000106 | ||
1677613 | Demarion | M | 200 | 2010 | 0.000105 | ||
1677618 | Gibson | M | 200 | 2010 | 0.000105 | ||
1677619 | Reagan | M | 200 | 2010 | 0.000105 | ||
1677620 | Cristofer | M | 199 | 2010 | 0.000105 | ||
1677621 | Daylen | M | 199 | 2010 | 0.000105 | ||
1677622 | Jordon | M | 199 | 2010 | 0.000105 | ||
1677623 | Dashawn | M | 198 | 2010 | 0.000104 | ||
1677624 | Masen | M | 198 | 2010 | 0.000104 | ||
1677625 | Rowen | M | 197 | 2010 | 0.000104 | ||
1677629 | Yousef | M | 197 | 2010 | 0.000104 | ||
1677631 | Thaddeus | M | 197 | 2010 | 0.000104 | ||
1677630 | Kadin | M | 197 | 2010 | 0.000104 | ||
1677628 | Dillan | M | 197 | 2010 | 0.000104 | ||
1677627 | Clarence | M | 197 | 2010 | 0.000104 | ||
1677626 | Slade | M | 196 | 2010 | 0.000103 | ||
1677634 | Clinton | M | 196 | 2010 | 0.000103 | ||
1677632 | Sheldon | M | 196 | 2010 | 0.000103 | ||
1677633 | Keshawn | M | 195 | 2010 | 0.000103 | ||
1677636 | Menachem | M | 195 | 2010 | 0.000103 | ||
1677637 | Joziah | M | 195 | 2010 | 0.000103 | ||
1677635 | Bailey | M | 194 | 2010 | 0.000102 | ||
1677638 | Camilo | M | 194 | 2010 | 0.000102 | ||
1677639 | Destin | M | 194 | 2010 | 0.000102 | ||
1677640 | Jaquan | M | 194 | 2010 | 0.000102 | ||
1677641 | Jaydan | M | 194 | 2010 | 0.000102 | ||
1677642 | Maxton | M | 193 | 2010 | 0.000102 |
1000 rows × 5 columns
prop_cumsum = df.sort_values(by='prop', ascending=False).prop.cumsum()
prop_cumsum
year sex 2010 M 1676644 0.011523 1676645 0.020934 1676646 0.029959 1676647 0.038930 1676648 0.047817 1676649 0.056579 1676650 0.065155 1676651 0.073414 1676652 0.081528 1676653 0.089621 1676654 0.097648 1676655 0.105406 1676656 0.112852 1676657 0.120276 1676658 0.127672 1676659 0.135023 1676660 0.142368 1676661 0.149603 1676662 0.156827 1676663 0.164021 1676664 0.170722 1676665 0.177191 1676666 0.183452 1676667 0.189655 1676668 0.195815 1676669 0.201832 1676670 0.207769 1676671 0.213578 1676672 0.219354 1676673 0.225070 ... 1677613 0.840147 1677615 0.840252 1677616 0.840358 1677617 0.840464 1677618 0.840569 1677619 0.840675 1677620 0.840780 1677621 0.840885 1677622 0.840990 1677623 0.841095 1677624 0.841199 1677625 0.841303 1677628 0.841407 1677626 0.841511 1677627 0.841615 1677630 0.841718 1677631 0.841822 1677629 0.841926 1677634 0.842029 1677632 0.842132 1677633 0.842236 1677636 0.842338 1677637 0.842441 1677635 0.842544 1677638 0.842646 1677639 0.842748 1677640 0.842850 1677641 0.842953 1677642 0.843055 1677645 0.843156 Name: prop, dtype: float64
cumsum 메쏘드는 누적합을 의미한다. 위 데이터에서 0.5에 도달할 때의 index는 searchsorted 메쏘드로 확인한다.
prop_cumsum.searchsorted(0.5)
array([116])
파이썬이 0부터 카운팅하므로, 117개의 이름이 50%를 차지함을 알 수 있다. 반면에,
df = boys[boys.year == 1900]
in1900 = df.sort_values(by='prop', ascending=False).prop.cumsum()
in1900.searchsorted(0.5) + 1
array([25])
1900년생은 25명이다. 확실히 다양성이 증가했다.
이를 종합하여 매년 어떻게 변화하는지 살펴보자.
def get_quantile_count(group, q=0.5):
group = group.sort_values(by='prop', ascending=False)
return (group.prop.cumsum().searchsorted(q) + 1)[0]
diversity = top1000.groupby(['year', 'sex']).apply(get_quantile_count)
diversity = diversity.unstack('sex')
diversity
sex | F | M |
---|---|---|
year | ||
1880 | 38 | 14 |
1881 | 38 | 14 |
1882 | 38 | 15 |
1883 | 39 | 15 |
1884 | 39 | 16 |
1885 | 40 | 16 |
1886 | 41 | 16 |
1887 | 41 | 17 |
1888 | 42 | 17 |
1889 | 43 | 18 |
1890 | 44 | 19 |
1891 | 44 | 20 |
1892 | 44 | 20 |
1893 | 44 | 21 |
1894 | 45 | 22 |
1895 | 46 | 22 |
1896 | 46 | 23 |
1897 | 46 | 23 |
1898 | 47 | 24 |
1899 | 47 | 25 |
1900 | 49 | 25 |
1901 | 49 | 25 |
1902 | 49 | 26 |
1903 | 49 | 27 |
1904 | 50 | 28 |
1905 | 50 | 28 |
1906 | 49 | 28 |
1907 | 50 | 30 |
1908 | 49 | 30 |
1909 | 49 | 30 |
... | ... | ... |
1981 | 78 | 35 |
1982 | 75 | 35 |
1983 | 71 | 34 |
1984 | 71 | 35 |
1985 | 72 | 36 |
1986 | 74 | 37 |
1987 | 75 | 39 |
1988 | 78 | 40 |
1989 | 83 | 43 |
1990 | 90 | 45 |
1991 | 95 | 48 |
1992 | 102 | 51 |
1993 | 107 | 54 |
1994 | 111 | 57 |
1995 | 115 | 60 |
1996 | 122 | 64 |
1997 | 129 | 67 |
1998 | 138 | 70 |
1999 | 146 | 73 |
2000 | 155 | 77 |
2001 | 164 | 81 |
2002 | 170 | 83 |
2003 | 178 | 87 |
2004 | 191 | 92 |
2005 | 199 | 96 |
2006 | 209 | 99 |
2007 | 223 | 103 |
2008 | 234 | 109 |
2009 | 241 | 114 |
2010 | 246 | 117 |
131 rows × 2 columns
diversity.plot(title="Number of popular names in top 50%")
<matplotlib.axes._subplots.AxesSubplot at 0x10ce56940>
남자이름 보단 여자이름이 더 다양한 것으로 나옴. 1980년대 이후 특히 증가함을 알 수 있다.
2007년에 출생아 이름 연구가 Laura Wattenberg는 남자이름의 마지막 글자 분포가 지난 100년에 걸처 유의하게 변해왔다고 한다. 확인해보자.
get_last_letter = lambda x: x[-1]
last_letters = names.name.map(get_last_letter)
last_letters.name = 'last_letter'
last_letters
0 y 1 a 2 a 3 h 4 e 5 t 6 a 7 e 8 a 9 h 10 e 11 a 12 a 13 e 14 a 15 a 16 a 17 e 18 e 19 e 20 e 21 l 22 e 23 e 24 e 25 a 26 e 27 h 28 e 29 e .. 1690754 n 1690755 n 1690756 n 1690757 n 1690758 l 1690759 n 1690760 a 1690761 o 1690762 h 1690763 i 1690764 h 1690765 n 1690766 r 1690767 n 1690768 n 1690769 n 1690770 n 1690771 i 1690772 n 1690773 b 1690774 e 1690775 t 1690776 n 1690777 r 1690778 n 1690779 e 1690780 e 1690781 s 1690782 n 1690783 x Name: last_letter, dtype: object
table = names.pivot_table('births', index=last_letters, columns=['sex', 'year'], aggfunc=sum)
table
sex | F | ... | M | ||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
year | 1880 | 1881 | 1882 | 1883 | 1884 | 1885 | 1886 | 1887 | 1888 | 1889 | ... | 2001 | 2002 | 2003 | 2004 | 2005 | 2006 | 2007 | 2008 | 2009 | 2010 |
last_letter | |||||||||||||||||||||
a | 31446.0 | 31581.0 | 36536.0 | 38330.0 | 43680.0 | 45408.0 | 49100.0 | 48942.0 | 59442.0 | 58631.0 | ... | 39124.0 | 38815.0 | 37825.0 | 38650.0 | 36838.0 | 36156.0 | 34654.0 | 32901.0 | 31430.0 | 28438.0 |
b | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | ... | 50950.0 | 49284.0 | 48065.0 | 45914.0 | 43144.0 | 42600.0 | 42123.0 | 39945.0 | 38862.0 | 38859.0 |
c | NaN | NaN | 5.0 | 5.0 | NaN | NaN | NaN | NaN | NaN | NaN | ... | 27113.0 | 27238.0 | 27697.0 | 26778.0 | 26078.0 | 26635.0 | 26864.0 | 25318.0 | 24048.0 | 23125.0 |
d | 609.0 | 607.0 | 734.0 | 810.0 | 916.0 | 862.0 | 1007.0 | 1027.0 | 1298.0 | 1374.0 | ... | 60838.0 | 55829.0 | 53391.0 | 51754.0 | 50670.0 | 51410.0 | 50595.0 | 47910.0 | 46172.0 | 44398.0 |
e | 33378.0 | 34080.0 | 40399.0 | 41914.0 | 48089.0 | 49616.0 | 53884.0 | 54353.0 | 66750.0 | 66663.0 | ... | 145395.0 | 144651.0 | 144769.0 | 142098.0 | 141123.0 | 142999.0 | 143698.0 | 140966.0 | 135496.0 | 129012.0 |
f | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | ... | 1758.0 | 1817.0 | 1819.0 | 1904.0 | 1985.0 | 1968.0 | 2090.0 | 2195.0 | 2212.0 | 2255.0 |
g | 7.0 | 5.0 | 12.0 | 8.0 | 24.0 | 11.0 | 18.0 | 25.0 | 44.0 | 28.0 | ... | 2151.0 | 2084.0 | 2009.0 | 1837.0 | 1882.0 | 1929.0 | 2040.0 | 2059.0 | 2396.0 | 2666.0 |
h | 4863.0 | 4784.0 | 5567.0 | 5701.0 | 6602.0 | 6624.0 | 7146.0 | 7141.0 | 8630.0 | 8826.0 | ... | 85959.0 | 88085.0 | 88226.0 | 89620.0 | 92497.0 | 98477.0 | 99414.0 | 100250.0 | 99979.0 | 98090.0 |
i | 61.0 | 78.0 | 81.0 | 76.0 | 84.0 | 92.0 | 85.0 | 105.0 | 141.0 | 134.0 | ... | 20980.0 | 23610.0 | 26011.0 | 28500.0 | 31317.0 | 33558.0 | 35231.0 | 38151.0 | 40912.0 | 42956.0 |
j | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | ... | 1069.0 | 1088.0 | 1203.0 | 1094.0 | 1291.0 | 1241.0 | 1254.0 | 1381.0 | 1416.0 | 1459.0 |
k | 13.0 | 15.0 | 11.0 | 17.0 | 21.0 | 18.0 | 27.0 | 19.0 | 21.0 | 22.0 | ... | 42477.0 | 42043.0 | 42296.0 | 41400.0 | 42151.0 | 42537.0 | 42136.0 | 39563.0 | 37507.0 | 35198.0 |
l | 2541.0 | 2911.0 | 3527.0 | 3848.0 | 4808.0 | 5144.0 | 5721.0 | 6175.0 | 7900.0 | 8395.0 | ... | 153648.0 | 153493.0 | 153862.0 | 152800.0 | 155312.0 | 156234.0 | 155203.0 | 150791.0 | 143751.0 | 133583.0 |
m | 58.0 | 57.0 | 81.0 | 86.0 | 79.0 | 75.0 | 103.0 | 90.0 | 123.0 | 137.0 | ... | 41967.0 | 42663.0 | 42790.0 | 43054.0 | 41600.0 | 42503.0 | 43860.0 | 44316.0 | 46278.0 | 46808.0 |
n | 3008.0 | 2959.0 | 3576.0 | 3837.0 | 4507.0 | 4735.0 | 5242.0 | 5512.0 | 6833.0 | 7103.0 | ... | 616099.0 | 630322.0 | 663419.0 | 676011.0 | 686326.0 | 720998.0 | 741355.0 | 733869.0 | 715388.0 | 688677.0 |
o | 30.0 | 49.0 | 35.0 | 47.0 | 74.0 | 84.0 | 93.0 | 97.0 | 134.0 | 142.0 | ... | 82146.0 | 83180.0 | 85423.0 | 88822.0 | 92001.0 | 96350.0 | 96895.0 | 91485.0 | 86423.0 | 81025.0 |
p | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | ... | 3419.0 | 3157.0 | 2982.0 | 2841.0 | 2768.0 | 2721.0 | 2739.0 | 2637.0 | 2595.0 | 2409.0 |
q | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | ... | 602.0 | 618.0 | 585.0 | 523.0 | 446.0 | 430.0 | 431.0 | 339.0 | 377.0 | 342.0 |
r | 481.0 | 417.0 | 590.0 | 640.0 | 718.0 | 799.0 | 917.0 | 910.0 | 1207.0 | 1214.0 | ... | 165377.0 | 164821.0 | 169878.0 | 169452.0 | 172069.0 | 176490.0 | 177207.0 | 174632.0 | 173200.0 | 166064.0 |
s | 1391.0 | 1316.0 | 1637.0 | 1794.0 | 2039.0 | 2127.0 | 2524.0 | 2803.0 | 3582.0 | 3569.0 | ... | 143791.0 | 139595.0 | 138632.0 | 139642.0 | 139913.0 | 143232.0 | 142155.0 | 137056.0 | 129861.0 | 123670.0 |
t | 2152.0 | 2165.0 | 2399.0 | 2554.0 | 2825.0 | 2889.0 | 3017.0 | 3140.0 | 3816.0 | 3784.0 | ... | 47688.0 | 44991.0 | 43765.0 | 43870.0 | 43369.0 | 43553.0 | 43437.0 | 43846.0 | 43674.0 | 43398.0 |
u | 380.0 | 427.0 | 410.0 | 444.0 | 490.0 | 495.0 | 511.0 | 476.0 | 541.0 | 469.0 | ... | 1833.0 | 1819.0 | 2052.0 | 2138.0 | 2129.0 | 2201.0 | 2311.0 | 2405.0 | 2417.0 | 2318.0 |
v | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | ... | 1209.0 | 1332.0 | 1652.0 | 1823.0 | 1794.0 | 2010.0 | 2295.0 | 2418.0 | 2589.0 | 2723.0 |
w | NaN | 5.0 | NaN | NaN | NaN | NaN | 5.0 | NaN | NaN | NaN | ... | 52265.0 | 50103.0 | 49079.0 | 47556.0 | 45464.0 | 43217.0 | 40251.0 | 36937.0 | 33181.0 | 30656.0 |
x | NaN | NaN | NaN | 7.0 | NaN | NaN | NaN | NaN | NaN | NaN | ... | 10691.0 | 11009.0 | 11718.0 | 12399.0 | 13025.0 | 13992.0 | 14306.0 | 14834.0 | 16640.0 | 16352.0 |
y | 10469.0 | 10404.0 | 12145.0 | 12063.0 | 13917.0 | 13927.0 | 14936.0 | 14980.0 | 17931.0 | 17601.0 | ... | 139109.0 | 134557.0 | 130569.0 | 128367.0 | 125190.0 | 123707.0 | 123397.0 | 122633.0 | 112922.0 | 110425.0 |
z | 106.0 | 95.0 | 106.0 | 141.0 | 148.0 | 150.0 | 202.0 | 188.0 | 238.0 | 277.0 | ... | 2840.0 | 2737.0 | 2722.0 | 2710.0 | 2903.0 | 3086.0 | 3301.0 | 3473.0 | 3633.0 | 3476.0 |
26 rows × 262 columns
연도가 너무 많으니 대표적은 3개의 연도만 확인해보기로 하자.
subtable = table.reindex(columns=[1910, 1960, 2010], level='year')
subtable.sum()
sex year F 1910 396416.0 1960 2022062.0 2010 1759010.0 M 1910 194198.0 1960 2132588.0 2010 1898382.0 dtype: float64
letter_prop = subtable / subtable.sum()
letter_prop
sex | F | M | ||||
---|---|---|---|---|---|---|
year | 1910 | 1960 | 2010 | 1910 | 1960 | 2010 |
last_letter | ||||||
a | 0.273390 | 0.341853 | 0.381240 | 0.005031 | 0.002440 | 0.014980 |
b | NaN | 0.000343 | 0.000256 | 0.002116 | 0.001834 | 0.020470 |
c | 0.000013 | 0.000024 | 0.000538 | 0.002482 | 0.007257 | 0.012181 |
d | 0.017028 | 0.001844 | 0.001482 | 0.113858 | 0.122908 | 0.023387 |
e | 0.336941 | 0.215133 | 0.178415 | 0.147556 | 0.083853 | 0.067959 |
f | NaN | 0.000010 | 0.000055 | 0.000783 | 0.004325 | 0.001188 |
g | 0.000144 | 0.000157 | 0.000374 | 0.002250 | 0.009488 | 0.001404 |
h | 0.051529 | 0.036224 | 0.075852 | 0.045562 | 0.037907 | 0.051670 |
i | 0.001526 | 0.039965 | 0.031734 | 0.000844 | 0.000603 | 0.022628 |
j | NaN | NaN | 0.000090 | NaN | NaN | 0.000769 |
k | 0.000121 | 0.000156 | 0.000356 | 0.036581 | 0.049384 | 0.018541 |
l | 0.043189 | 0.033867 | 0.026356 | 0.065016 | 0.104904 | 0.070367 |
m | 0.001201 | 0.008613 | 0.002588 | 0.058044 | 0.033827 | 0.024657 |
n | 0.079240 | 0.130687 | 0.140210 | 0.143415 | 0.152522 | 0.362771 |
o | 0.001660 | 0.002439 | 0.001243 | 0.017065 | 0.012829 | 0.042681 |
p | 0.000018 | 0.000023 | 0.000020 | 0.003172 | 0.005675 | 0.001269 |
q | NaN | NaN | 0.000030 | NaN | NaN | 0.000180 |
r | 0.013390 | 0.006764 | 0.018025 | 0.064481 | 0.031034 | 0.087477 |
s | 0.039042 | 0.012764 | 0.013332 | 0.130815 | 0.102730 | 0.065145 |
t | 0.027438 | 0.015201 | 0.007830 | 0.072879 | 0.065655 | 0.022861 |
u | 0.000684 | 0.000574 | 0.000417 | 0.000124 | 0.000057 | 0.001221 |
v | NaN | 0.000060 | 0.000117 | 0.000113 | 0.000037 | 0.001434 |
w | 0.000020 | 0.000031 | 0.001182 | 0.006329 | 0.007711 | 0.016148 |
x | 0.000015 | 0.000037 | 0.000727 | 0.003965 | 0.001851 | 0.008614 |
y | 0.110972 | 0.152569 | 0.116828 | 0.077349 | 0.160987 | 0.058168 |
z | 0.002439 | 0.000659 | 0.000704 | 0.000170 | 0.000184 | 0.001831 |
이를 차트로 표시해보면,
import matplotlib.pyplot as plt
fig, axes = plt.subplots(2, 1, figsize=(10,8))
letter_prop['M'].plot(kind='bar', rot=0, ax=axes[0], title='Male')
letter_prop['F'].plot(kind='bar', rot=0, ax=axes[1], title='Female', legend=False)
<matplotlib.axes._subplots.AxesSubplot at 0x10d7b0d68>
남자의 경우, 1960년대 이후, "n"으로 끝나는 이름이 현저히 늘었다. 이를 전체 그룹에 대해 확장해보자.
letter_prop = table / table.sum()
dny_ts = letter_prop.ix[['d', 'n', 'y'], 'M'].T
dny_ts
last_letter | d | n | y |
---|---|---|---|
year | |||
1880 | 0.083055 | 0.153213 | 0.075760 |
1881 | 0.083247 | 0.153214 | 0.077451 |
1882 | 0.085340 | 0.149560 | 0.077537 |
1883 | 0.084066 | 0.151646 | 0.079144 |
1884 | 0.086120 | 0.149915 | 0.080405 |
1885 | 0.085472 | 0.146361 | 0.081882 |
1886 | 0.087647 | 0.149659 | 0.081681 |
1887 | 0.089072 | 0.148838 | 0.082870 |
1888 | 0.087707 | 0.151286 | 0.084919 |
1889 | 0.091934 | 0.151976 | 0.086328 |
1890 | 0.093834 | 0.146470 | 0.086277 |
1891 | 0.094478 | 0.148353 | 0.084933 |
1892 | 0.096388 | 0.144857 | 0.084883 |
1893 | 0.098318 | 0.142558 | 0.084643 |
1894 | 0.100462 | 0.142112 | 0.085554 |
1895 | 0.100019 | 0.143350 | 0.083332 |
1896 | 0.102881 | 0.140631 | 0.083922 |
1897 | 0.101987 | 0.140112 | 0.083283 |
1898 | 0.104887 | 0.139614 | 0.090633 |
1899 | 0.105020 | 0.140607 | 0.084807 |
1900 | 0.102946 | 0.137645 | 0.084661 |
1901 | 0.106792 | 0.141428 | 0.081754 |
1902 | 0.108022 | 0.140641 | 0.081901 |
1903 | 0.109577 | 0.141337 | 0.080309 |
1904 | 0.109335 | 0.143145 | 0.080739 |
1905 | 0.110226 | 0.142429 | 0.079331 |
1906 | 0.111836 | 0.141447 | 0.078786 |
1907 | 0.112689 | 0.143328 | 0.079046 |
1908 | 0.113899 | 0.143146 | 0.078593 |
1909 | 0.115500 | 0.144204 | 0.077386 |
... | ... | ... | ... |
1981 | 0.069564 | 0.247668 | 0.109612 |
1982 | 0.067343 | 0.247982 | 0.107810 |
1983 | 0.064590 | 0.250570 | 0.103872 |
1984 | 0.062247 | 0.249121 | 0.104434 |
1985 | 0.060067 | 0.249074 | 0.106783 |
1986 | 0.058999 | 0.248461 | 0.108102 |
1987 | 0.057410 | 0.248466 | 0.108872 |
1988 | 0.054987 | 0.250193 | 0.108163 |
1989 | 0.052868 | 0.251095 | 0.106309 |
1990 | 0.049690 | 0.254481 | 0.104817 |
1991 | 0.046487 | 0.260756 | 0.103390 |
1992 | 0.043886 | 0.269240 | 0.101575 |
1993 | 0.042119 | 0.271248 | 0.100591 |
1994 | 0.039973 | 0.278569 | 0.096975 |
1995 | 0.038017 | 0.284643 | 0.091720 |
1996 | 0.037067 | 0.289856 | 0.087609 |
1997 | 0.036652 | 0.293351 | 0.083793 |
1998 | 0.035442 | 0.298259 | 0.079016 |
1999 | 0.034149 | 0.304703 | 0.076184 |
2000 | 0.032753 | 0.313060 | 0.073000 |
2001 | 0.031352 | 0.317495 | 0.071687 |
2002 | 0.028794 | 0.325086 | 0.069397 |
2003 | 0.027069 | 0.336344 | 0.066197 |
2004 | 0.026118 | 0.341151 | 0.064781 |
2005 | 0.025420 | 0.344319 | 0.062806 |
2006 | 0.025075 | 0.351666 | 0.060338 |
2007 | 0.024451 | 0.358274 | 0.059634 |
2008 | 0.023574 | 0.361101 | 0.060342 |
2009 | 0.023398 | 0.362523 | 0.057223 |
2010 | 0.023387 | 0.362771 | 0.058168 |
131 rows × 3 columns
이를 차트로 표시하면,
dny_ts.plot()
<matplotlib.axes._subplots.AxesSubplot at 0x10fa79278>
전체 연도로 패턴을 보니, 확실히 "n"으로 끝나는 빈도가 증가하고 있다.
성별이 바뀌는 이름들이 있다. Lesley, Leslie 이름이 대표적인 예. 이를 구체적으로 확인해보자.
all_names = top1000.name.unique()
mask = np.array(['lesl' in x.lower() for x in all_names])
lesley_like = all_names[mask]
lesley_like
array(['Leslie', 'Lesley', 'Leslee', 'Lesli', 'Lesly'], dtype=object)
filtered = top1000[top1000.name.isin(lesley_like)]
filtered.groupby('name').births.sum()
name Leslee 1082 Lesley 35022 Lesli 929 Leslie 370429 Lesly 10067 Name: births, dtype: int64
table = filtered.pivot_table('births', index='year', columns='sex', aggfunc=sum)
table
sex | F | M |
---|---|---|
year | ||
1880 | 8.0 | 79.0 |
1881 | 11.0 | 92.0 |
1882 | 9.0 | 128.0 |
1883 | 7.0 | 125.0 |
1884 | 15.0 | 125.0 |
1885 | 10.0 | 122.0 |
1886 | 8.0 | 136.0 |
1887 | 12.0 | 166.0 |
1888 | 23.0 | 175.0 |
1889 | 23.0 | 155.0 |
1890 | 20.0 | 181.0 |
1891 | 28.0 | 164.0 |
1892 | 22.0 | 207.0 |
1893 | 26.0 | 185.0 |
1894 | 36.0 | 223.0 |
1895 | 22.0 | 235.0 |
1896 | 27.0 | 237.0 |
1897 | 34.0 | 222.0 |
1898 | 24.0 | 236.0 |
1899 | 18.0 | 181.0 |
1900 | 30.0 | 285.0 |
1901 | 29.0 | 204.0 |
1902 | 37.0 | 251.0 |
1903 | 24.0 | 244.0 |
1904 | 30.0 | 243.0 |
1905 | 35.0 | 247.0 |
1906 | 29.0 | 263.0 |
1907 | 34.0 | 273.0 |
1908 | 41.0 | 290.0 |
1909 | 35.0 | 292.0 |
... | ... | ... |
1981 | 5796.0 | 500.0 |
1982 | 5814.0 | 430.0 |
1983 | 4975.0 | 414.0 |
1984 | 4419.0 | 367.0 |
1985 | 4168.0 | 331.0 |
1986 | 3741.0 | 379.0 |
1987 | 3666.0 | 290.0 |
1988 | 3555.0 | 318.0 |
1989 | 3259.0 | 327.0 |
1990 | 3268.0 | 295.0 |
1991 | 2920.0 | 277.0 |
1992 | 2836.0 | 216.0 |
1993 | 2607.0 | 201.0 |
1994 | 2685.0 | 207.0 |
1995 | 2782.0 | 186.0 |
1996 | 3584.0 | 176.0 |
1997 | 3847.0 | 158.0 |
1998 | 4289.0 | NaN |
1999 | 4693.0 | NaN |
2000 | 5019.0 | NaN |
2001 | 4920.0 | NaN |
2002 | 4708.0 | NaN |
2003 | 4924.0 | NaN |
2004 | 4694.0 | NaN |
2005 | 4284.0 | NaN |
2006 | 4166.0 | NaN |
2007 | 3805.0 | NaN |
2008 | 3022.0 | NaN |
2009 | 2573.0 | NaN |
2010 | 2060.0 | NaN |
131 rows × 2 columns
table = table.div(table.sum(1), axis=0)
table
sex | F | M |
---|---|---|
year | ||
1880 | 0.091954 | 0.908046 |
1881 | 0.106796 | 0.893204 |
1882 | 0.065693 | 0.934307 |
1883 | 0.053030 | 0.946970 |
1884 | 0.107143 | 0.892857 |
1885 | 0.075758 | 0.924242 |
1886 | 0.055556 | 0.944444 |
1887 | 0.067416 | 0.932584 |
1888 | 0.116162 | 0.883838 |
1889 | 0.129213 | 0.870787 |
1890 | 0.099502 | 0.900498 |
1891 | 0.145833 | 0.854167 |
1892 | 0.096070 | 0.903930 |
1893 | 0.123223 | 0.876777 |
1894 | 0.138996 | 0.861004 |
1895 | 0.085603 | 0.914397 |
1896 | 0.102273 | 0.897727 |
1897 | 0.132812 | 0.867188 |
1898 | 0.092308 | 0.907692 |
1899 | 0.090452 | 0.909548 |
1900 | 0.095238 | 0.904762 |
1901 | 0.124464 | 0.875536 |
1902 | 0.128472 | 0.871528 |
1903 | 0.089552 | 0.910448 |
1904 | 0.109890 | 0.890110 |
1905 | 0.124113 | 0.875887 |
1906 | 0.099315 | 0.900685 |
1907 | 0.110749 | 0.889251 |
1908 | 0.123867 | 0.876133 |
1909 | 0.107034 | 0.892966 |
... | ... | ... |
1981 | 0.920584 | 0.079416 |
1982 | 0.931134 | 0.068866 |
1983 | 0.923177 | 0.076823 |
1984 | 0.923318 | 0.076682 |
1985 | 0.926428 | 0.073572 |
1986 | 0.908010 | 0.091990 |
1987 | 0.926694 | 0.073306 |
1988 | 0.917893 | 0.082107 |
1989 | 0.908812 | 0.091188 |
1990 | 0.917205 | 0.082795 |
1991 | 0.913356 | 0.086644 |
1992 | 0.929227 | 0.070773 |
1993 | 0.928419 | 0.071581 |
1994 | 0.928423 | 0.071577 |
1995 | 0.937332 | 0.062668 |
1996 | 0.953191 | 0.046809 |
1997 | 0.960549 | 0.039451 |
1998 | 1.000000 | NaN |
1999 | 1.000000 | NaN |
2000 | 1.000000 | NaN |
2001 | 1.000000 | NaN |
2002 | 1.000000 | NaN |
2003 | 1.000000 | NaN |
2004 | 1.000000 | NaN |
2005 | 1.000000 | NaN |
2006 | 1.000000 | NaN |
2007 | 1.000000 | NaN |
2008 | 1.000000 | NaN |
2009 | 1.000000 | NaN |
2010 | 1.000000 | NaN |
131 rows × 2 columns
table.plot(style={'M': 'k-', 'F': 'k--'})
<matplotlib.axes._subplots.AxesSubplot at 0x1102b5630>
"Lesl~"로 시작하는 이름은 1940년대에는 남자이름이었다가 그후 빠르게 여자이름으로 바뀜.