連接:https://pan.baidu.com/s/1wIyRZfgR7EjQ_KFP5-cnaA 提取碼:g0zy
由於獲取到的數據是根據出生年份分爲了多個文件,其中文件內部的數據也是簡單的經過逗號分隔而成的,因此須要規整一下:python
years = range(1880,2018) pieces = [] columns = ['name','sex','births'] # 字段參數 for year in years: path = "D:\\data\\names\\yob%s.txt"%year # 加入本身相應的文件路徑 frame = pd.read_csv(path,names=columns) frame['year'] = year # 添加出生年份列 pieces.append(frame) names = pd.concat(pieces,,ignore_index=True) # 合併數據集,ignore_index=True刪除原索引,生成新索引
經過以上操做就能夠將全部的數據文件合併爲一個數據集,接下來就能夠進行具體的數據分析app
有了以上數據集就能夠利用他們完成不少工做,例如:字體
一、以性別和出生年份分析總出生數 二、分析命名趨勢 三、分析名字中最後一個字母的變化趨勢
接下來就主要以以上幾種方式進行分析,有其餘方案也能夠本身添加3d
首先,經過groupby或pivot_table在year和sex上對其進行聚合:code
total_births = names.pivot_table('births',index='year',columns='sex',aggfunc=sum) total_births.tail() # 展現最後幾列數據 運行結果: sex F M year 2013 1750321 1886989 2014 1781072 1915239 2015 1778883 1909804 2016 1763916 1889052 2017 1711811 1834490
如今就能夠經過以上獲得的total_births將歷年出生孩子總數走勢圖繪製出來blog
# 補充(修改走勢圖標題爲中文): import matplotlib as mpl mpl.rcParams['font.sans-serif']=['SimHei'] #指定默認字體 SimHei爲黑體 mpl.rcParams['axes.unicode_minus']=False #用來正常顯示負號 ----------------------------------------------- total_births.plot(title='以性別和出生年份分組的出生總數')
以上數據總量相對來講仍是比較大的,因此接下來能夠經過一系列操做只取每一年取名頻率前1000的數據進行分析。索引
# 插入一個prop列,用於存放指定名字的嬰兒數相對於總出生數的比例。先按year和sex分組,而後再將新列加到各個分組上: def add_prop(group): group['prop'] = group.births / group.births.sum() return group names = names.groupby(['year','sex').apply(add_prop) ----------------------------------------------- 運行結果: 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 ... ... ... ... ... ... 1924660 Zykai M 5 2017 0.000003 1924661 Zykeem M 5 2017 0.000003 1924662 Zylin M 5 2017 0.000003 1924663 Zylis M 5 2017 0.000003 1924664 Zyrie M 5 2017 0.000003
接下來,就以上數據作一個簡單的小檢查,驗證全部分組的prop的1unicode
names.groupby(['year','sex']).prop.sum() # 驗證全部分組的總和是否爲1 運行結果: year sex 1880 F 1.0 M 1.0 1881 F 1.0 M 1.0 1882 F 1.0 ... 2015 M 1.0 2016 F 1.0 M 1.0 2017 F 1.0 M 1.0 Name: prop, Length: 276, dtype: float64
而後就能夠取出一個以上數據的子集,每對sex/year組合的前1000個名字。get
def get_top_1000(group): return group.sort_values(by='births',ascending=False)[:1000] grouped = names.groupby(['year','sex']) top_1000 = grouped.apply(get_top_1000) top_1000.reset_index(inplace=True,drop=True)
接下來分析的數據集相對來講就比較小了。數據分析
# 將要分析的數據分爲男女兩個部分 boys = top_1000[top_1000.sex == 'M'] girls = top_1000[top_1000.sex == 'F']
建立一個透視表,以年份爲索引,名字爲聚合列
total_births = top_1000.pivot_table('births',index='year',columns='name',aggfunc=sum)
而後就能夠以幾個經常使用名字繪製曲線圖:
subset = total_births[['John','Harry','Mary','Marilyn']] subset.plot(subplots=True,title='命名趨勢')
根據以上數據能夠發現美國家長對於給孩子起這些常見名字的趨勢。
# 從名稱中取出最後一個字母 get_last_letter = lambda x:x[-1] last_letters = names.name.map(get_last_letter) # 取出每一個名字最後一個字母 last_letters.name = 'last_letter' # 定義新列的名字 table = names.pivot_table('births',index=last_letters,columns=['sex','year'],aggfunc=sum) ---------------------------------------------- # 取出每隔45年的數據 subtable = table.reindex(columns=[1880,1925,1970,2015],level='year') # 只取部分數據查看針對性數據 subtable.head() # 查看前幾行 運行結果: sex F M year 1910 1960 2010 1910 1960 2010 last_letter a 108397.0 691250.0 676646.0 977.0 5212.0 28859.0 b NaN 694.0 455.0 411.0 3914.0 39264.0 c 5.0 49.0 955.0 482.0 15460.0 23341.0 d 6751.0 3730.0 2640.0 22113.0 262136.0 44817.0 e 133600.0 435043.0 316665.0 28665.0 178785.0 130228.0 ---------------------------------------------- letter_prop = subtable / subtable.sum() # 各性別各末位字母佔總出生人數的比例 letter_prop 運行結果: sex F M year 1910 1960 2010 1910 1960 2010 last_letter a 0.273383 0.341861 0.381261 0.005031 0.002444 0.015063 b NaN 0.000343 0.000256 0.002116 0.001836 0.020493 c 0.000013 0.000024 0.000538 0.002482 0.007250 0.012183 d 0.017026 0.001845 0.001488 0.113860 0.122932 0.023392 e 0.336947 0.215153 0.178427 0.147596 0.083844 0.067971 ... ... ... ... ... ... ... v NaN 0.000060 0.000117 0.000113 0.000036 0.001449 w 0.000020 0.000031 0.001189 0.006323 0.007709 0.016176 x 0.000015 0.000037 0.000729 0.003965 0.001851 0.008597 y 0.110975 0.152552 0.116769 0.077343 0.160976 0.058182 z 0.002436 0.000658 0.000700 0.000170 0.000184 0.001825 ---------------------------------------------- fig,axes = plt.subplots(2,1,figsize=(15,10)) # 生成兩個子圖,分別繪製男女生趨勢 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')
接下來就能夠以出現概率最高的三個字母對男生進行分析:
letter_prop_sum = table / table.sum() # 以以前建立的完整表計算 dny_ts = letter_prop_sum.loc[['d','n','y'],'M'].T # 以標籤索引取出的d,n,y字母的數據,最後進行轉置 dny_ts.plot(title='各年名字中以d/n/y結尾的男孩人數比例')