《利用Python进行数据分析》学习笔记ch02-3(3)

索引:
pandas.read_csv
pandas.concat
ignore_index=True
groupby或pivot_table进行聚合
np.allclose
计算prop的累计和cumsum
searchsorted

1880-2010年间全美婴儿姓名

由于这是一个非常标准的以逗号隔开的格式,所以可以用pandas.read_csv将其加载到DataFrame

import pandas as pd
names1880=pd.read_csv('C:\\pytest\\ch02\\names\\yob1880.txt',names=['name','sex','births'])
names1880
namesexbirths
0MaryF7065
1AnnaF2604
2EmmaF2003
3ElizabethF1939
4MinnieF1746
5MargaretF1578
6IdaF1472
7AliceF1414
8BerthaF1320
9SarahF1288
10AnnieF1258
11ClaraF1226
12EllaF1156
13FlorenceF1063
14CoraF1045
15MarthaF1040
16LauraF1012
17NellieF995
18GraceF982
19CarrieF949
20MaudeF858
21MabelF808
22BessieF794
23JennieF793
24GertrudeF787
25JuliaF783
26HattieF769
27EdithF768
28MattieF704
29RoseF700
1970PhiloM5
1971PhineasM5
1972PresleyM5
1973RansomM5
1974ReeceM5
1975ReneM5
1976RoswellM5
1977RowlandM5
1978SampsonM5
1979SamualM5
1980SantosM5
1981SchuylerM5
1982SheppardM5
1983SpurgeonM5
1984StarlingM5
1985SylvanusM5
1986TheadoreM5
1987TheophileM5
1988TilmonM5
1989TommyM5
1990UnknownM5
1991VannM5
1992WesM5
1993WinstonM5
1994WoodM5
1995WoodieM5
1996WorthyM5
1997WrightM5
1998YorkM5
1999ZachariahM5

2000 rows × 3 columns

用births列的sex分组小计表示该年度的births总计

 names1880.groupby('sex').births.sum()
sex
F     90993
M    110493
Name: births, dtype: int64

由于该数据集按年度被分隔成对个文件,所以首先要将所有数据都组装到一个DataFrame里面,并加上一个year字段。使用pandas.concat即可达到这个目的。

years=range(1880,2011)
pieces=[]
columns=['name','sex','births']
for year in years:
    path = 'C:\\pytest\\ch02\\names\\yob%d.txt' % year
    frame = pd.read_csv(path,names=columns)
    frame['year']=year
    pieces.append(frame)
names = pd.concat(pieces,ignore_index=True)

注意:
第一,concat默认是按行将多个DataFrame组合到一起的;
第二,必须指定ignore_index=True,因为我们不希望保留read_csv所返回的原始行号。
现在我们就得到了一个非常大的DataFrame,它含有全部的名字数据。

names
namesexbirthsyear
0MaryF70651880
1AnnaF26041880
2EmmaF20031880
3ElizabethF19391880
4MinnieF17461880
5MargaretF15781880
6IdaF14721880
7AliceF14141880
8BerthaF13201880
9SarahF12881880
10AnnieF12581880
11ClaraF12261880
12EllaF11561880
13FlorenceF10631880
14CoraF10451880
15MarthaF10401880
16LauraF10121880
17NellieF9951880
18GraceF9821880
19CarrieF9491880
20MaudeF8581880
21MabelF8081880
22BessieF7941880
23JennieF7931880
24GertrudeF7871880
25JuliaF7831880
26HattieF7691880
27EdithF7681880
28MattieF7041880
29RoseF7001880
1690754ZaviyonM52010
1690755ZaybrienM52010
1690756ZayshawnM52010
1690757ZayyanM52010
1690758ZealM52010
1690759ZealanM52010
1690760ZechariaM52010
1690761ZeferinoM52010
1690762ZekariahM52010
1690763ZekiM52010
1690764ZeriahM52010
1690765ZeshanM52010
1690766ZhyierM52010
1690767ZildjianM52010
1690768ZinnM52010
1690769ZishanM52010
1690770ZivenM52010
1690771ZmariM52010
1690772ZorenM52010
1690773ZuhaibM52010
1690774ZyeireM52010
1690775ZygmuntM52010
1690776ZykerionM52010
1690777ZylarM52010
1690778ZylinM52010
1690779ZymaireM52010
1690780ZyonneM52010
1690781ZyquariusM52010
1690782ZyranM52010
1690783ZzyzxM52010

1690784 rows × 4 columns

有了这些数据,我们就可以利用groupby或pivot_table在year和sex级别上对其进行聚合了。如图,按性别和年度统计的总出生数。

total_births = names.pivot_table('births',index='year',columns='sex',aggfunc=sum)
total_births.tail()
sexFM
year
200618964682050234
200719168882069242
200818836452032310
200918276431973359
201017590101898382
import matplotlib.pyplot as plot
total_births.plot(title='Total births by sex and year')
plot.show()

这里写图片描述
下面插入一个prop列,用于存放指定名字的婴儿数相对于总出生数的比例。

def add_prop(group):
     births = group.births.astype(float)
     group['prop'] = births/births.sum()
     return group
names = names.groupby(['year','sex']).apply(add_prop)
names
namesexbirthsyearprop
0MaryF706518800.077643
1AnnaF260418800.028618
2EmmaF200318800.022013
3ElizabethF193918800.021309
4MinnieF174618800.019188
5MargaretF157818800.017342
6IdaF147218800.016177
7AliceF141418800.015540
8BerthaF132018800.014507
9SarahF128818800.014155
10AnnieF125818800.013825
11ClaraF122618800.013474
12EllaF115618800.012704
13FlorenceF106318800.011682
14CoraF104518800.011484
15MarthaF104018800.011429
16LauraF101218800.011122
17NellieF99518800.010935
18GraceF98218800.010792
19CarrieF94918800.010429
20MaudeF85818800.009429
21MabelF80818800.008880
22BessieF79418800.008726
23JennieF79318800.008715
24GertrudeF78718800.008649
25JuliaF78318800.008605
26HattieF76918800.008451
27EdithF76818800.008440
28MattieF70418800.007737
29RoseF70018800.007693
1690754ZaviyonM520100.000003
1690755ZaybrienM520100.000003
1690756ZayshawnM520100.000003
1690757ZayyanM520100.000003
1690758ZealM520100.000003
1690759ZealanM520100.000003
1690760ZechariaM520100.000003
1690761ZeferinoM520100.000003
1690762ZekariahM520100.000003
1690763ZekiM520100.000003
1690764ZeriahM520100.000003
1690765ZeshanM520100.000003
1690766ZhyierM520100.000003
1690767ZildjianM520100.000003
1690768ZinnM520100.000003
1690769ZishanM520100.000003
1690770ZivenM520100.000003
1690771ZmariM520100.000003
1690772ZorenM520100.000003
1690773ZuhaibM520100.000003
1690774ZyeireM520100.000003
1690775ZygmuntM520100.000003
1690776ZykerionM520100.000003
1690777ZylarM520100.000003
1690778ZylinM520100.000003
1690779ZymaireM520100.000003
1690780ZyonneM520100.000003
1690781ZyquariusM520100.000003
1690782ZyranM520100.000003
1690783ZzyzxM520100.000003

1690784 rows × 5 columns

在执行这样的分组处理时,一般都应该做一些有效性检查。由于这是一个浮点型数据,所以可以用np.allclose来检查这个分组总计值是否足够近似于1

import numpy as np
np.allclose(names.groupby(['year','sex']).prop.sum(),1)
True

为了便于进一步分析,取出该数据的一个子集:每对sex/year组合的前1000个名字。这也是一个分组操作。

def get_top1000(group):
    return group.sort_index(by='births',ascending=False)[:1000]
grouped = names.groupby(['year','sex'])
top1000 = grouped.apply(get_top1000)
C:\Anaconda3\lib\site-packages\ipykernel\__main__.py:2: FutureWarning: by argument to sort_index is deprecated, pls use .sort_values(by=...)
  from ipykernel import kernelapp as app
top1000
namesexbirthsyearprop
yearsex
1880F0MaryF706518800.077643
1AnnaF260418800.028618
2EmmaF200318800.022013
3ElizabethF193918800.021309
4MinnieF174618800.019188
5MargaretF157818800.017342
6IdaF147218800.016177
7AliceF141418800.015540
8BerthaF132018800.014507
9SarahF128818800.014155
10AnnieF125818800.013825
11ClaraF122618800.013474
12EllaF115618800.012704
13FlorenceF106318800.011682
14CoraF104518800.011484
15MarthaF104018800.011429
16LauraF101218800.011122
17NellieF99518800.010935
18GraceF98218800.010792
19CarrieF94918800.010429
20MaudeF85818800.009429
21MabelF80818800.008880
22BessieF79418800.008726
23JennieF79318800.008715
24GertrudeF78718800.008649
25JuliaF78318800.008605
26HattieF76918800.008451
27EdithF76818800.008440
28MattieF70418800.007737
29RoseF70018800.007693
2010M1677617YairM20120100.000106
1677616TalanM20120100.000106
1677614KeyonM20120100.000106
1677613KaelM20120100.000106
1677618DemarionM20020100.000105
1677619GibsonM20020100.000105
1677620ReaganM20020100.000105
1677621CristoferM19920100.000105
1677622DaylenM19920100.000105
1677623JordonM19920100.000105
1677624DashawnM19820100.000104
1677625MasenM19820100.000104
1677629RowenM19720100.000104
1677631YousefM19720100.000104
1677630ThaddeusM19720100.000104
1677628KadinM19720100.000104
1677627DillanM19720100.000104
1677626ClarenceM19720100.000104
1677634SladeM19620100.000103
1677632ClintonM19620100.000103
1677633SheldonM19620100.000103
1677636KeshawnM19520100.000103
1677637MenachemM19520100.000103
1677635JoziahM19520100.000103
1677638BaileyM19420100.000102
1677639CamiloM19420100.000102
1677640DestinM19420100.000102
1677641JaquanM19420100.000102
1677642JaydanM19420100.000102
1677645MaxtonM19320100.000102

261877 rows × 5 columns

分析命名趋势

利用刚才生产的top1000数据集,就可以开始分析各种命名趋势。

boys=top1000[top1000.sex == 'M']
girls=top1000[top1000.sex == 'F']
import matplotlib.pyplot as plot
total_births = top1000.pivot_table('births',index='year',columns='name',aggfunc=sum)
total_births
nameAadenAaliyahAaravAaronAarushAbAbagailAbbAbbeyAbbieZoaZoeZoeyZoieZolaZollieZonaZoraZulaZuri
year
1880NaNNaNNaN102.0NaNNaNNaNNaNNaN71.08.023.0NaNNaN7.0NaN8.028.027.0NaN
1881NaNNaNNaN94.0NaNNaNNaNNaNNaN81.0NaN22.0NaNNaN10.0NaN9.021.027.0NaN
1882NaNNaNNaN85.0NaNNaNNaNNaNNaN80.08.025.0NaNNaN9.0NaN17.032.021.0NaN
1883NaNNaNNaN105.0NaNNaNNaNNaNNaN79.0NaN23.0NaNNaN10.0NaN11.035.025.0NaN
1884NaNNaNNaN97.0NaNNaNNaNNaNNaN98.013.031.0NaNNaN14.06.08.058.027.0NaN
1885NaNNaNNaN88.0NaN6.0NaNNaNNaN88.06.027.0NaNNaN12.06.014.048.038.0NaN
1886NaNNaNNaN86.0NaNNaNNaNNaNNaN84.013.025.0NaNNaN8.0NaN20.052.043.0NaN
1887NaNNaNNaN78.0NaNNaNNaNNaNNaN104.09.034.0NaNNaN23.0NaN28.046.033.0NaN
1888NaNNaNNaN90.0NaNNaNNaNNaNNaN137.011.042.0NaNNaN23.07.030.042.045.0NaN
1889NaNNaNNaN85.0NaNNaNNaNNaNNaN107.014.029.0NaNNaN22.0NaN29.053.055.0NaN
1890NaNNaNNaN96.0NaNNaNNaN6.0NaN140.0NaN42.0NaNNaN32.07.027.060.065.0NaN
1891NaNNaNNaN69.0NaNNaNNaNNaNNaN124.0NaN34.0NaNNaN29.06.014.052.045.0NaN
1892NaNNaNNaN95.0NaNNaNNaNNaNNaN119.0NaN34.0NaNNaN27.0NaN25.066.053.0NaN
1893NaNNaNNaN81.0NaNNaNNaNNaNNaN115.0NaN23.0NaNNaN34.06.015.067.070.0NaN
1894NaNNaNNaN79.0NaNNaNNaNNaNNaN118.0NaN28.0NaNNaN51.0NaN23.066.064.0NaN
1895NaNNaNNaN94.0NaNNaNNaNNaNNaN92.0NaN34.0NaNNaN60.011.038.055.055.0NaN
1896NaNNaNNaN69.0NaNNaNNaNNaNNaN121.0NaN36.0NaNNaN47.0NaN38.072.065.0NaN
1897NaNNaNNaN87.0NaNNaNNaNNaNNaN97.0NaN35.0NaNNaN51.0NaN28.067.079.0NaN
1898NaNNaNNaN89.0NaNNaNNaNNaNNaN120.0NaN30.0NaNNaN62.0NaN28.065.083.0NaN
1899NaNNaNNaN71.0NaNNaNNaNNaNNaN87.0NaN27.0NaNNaN49.06.031.056.060.0NaN
1900NaNNaNNaN104.0NaNNaNNaNNaNNaN112.0NaN26.0NaNNaN48.09.044.099.071.0NaN
1901NaNNaNNaN80.0NaNNaNNaNNaNNaN87.0NaN26.0NaNNaN56.0NaN31.058.057.0NaN
1902NaNNaNNaN78.0NaNNaNNaNNaNNaN91.0NaN34.0NaNNaN58.0NaN23.058.066.0NaN
1903NaNNaNNaN93.0NaNNaNNaNNaNNaN91.0NaN19.0NaNNaN64.0NaN41.083.074.0NaN
1904NaNNaNNaN117.0NaNNaNNaNNaNNaN80.0NaN27.0NaNNaN46.0NaN35.054.074.0NaN
1905NaNNaNNaN96.0NaNNaNNaNNaNNaN73.0NaN24.0NaNNaN66.08.024.055.061.0NaN
1906NaNNaNNaN96.0NaNNaNNaNNaNNaN72.0NaN19.0NaNNaN59.0NaN37.064.058.0NaN
1907NaNNaNNaN130.0NaNNaNNaNNaNNaN79.0NaN19.0NaNNaN53.011.039.092.072.0NaN
1908NaNNaNNaN114.0NaNNaNNaNNaNNaN84.0NaN23.0NaNNaN70.0NaN31.059.053.0NaN
1909NaNNaNNaN142.0NaNNaNNaNNaNNaN57.0NaN22.0NaNNaN59.0NaN39.057.076.0NaN
1981NaNNaNNaN14832.0NaNNaNNaNNaN383.0292.0NaNNaNNaNNaNNaNNaNNaNNaNNaNNaN
1982NaNNaNNaN14538.0NaNNaNNaNNaN372.0275.0NaNNaNNaNNaNNaNNaNNaNNaNNaNNaN
1983NaNNaNNaN14627.0NaNNaNNaNNaN419.0223.0NaN174.0NaNNaNNaNNaNNaNNaNNaNNaN
1984NaNNaNNaN13387.0NaNNaNNaNNaN357.0249.0NaN200.0NaNNaNNaNNaNNaNNaNNaNNaN
1985NaNNaNNaN13123.0NaNNaNNaNNaN314.0233.0NaN193.0NaNNaNNaNNaNNaNNaNNaNNaN
1986NaNNaNNaN12685.0NaNNaNNaNNaN369.0228.0NaN213.0NaNNaNNaNNaNNaNNaNNaNNaN
1987NaNNaNNaN12676.0NaNNaNNaNNaN327.0228.0NaN248.0NaNNaNNaNNaNNaNNaNNaNNaN
1988NaNNaNNaN14393.0NaNNaNNaNNaN404.0226.0NaN238.0NaNNaNNaNNaNNaNNaNNaNNaN
1989NaNNaNNaN15312.0NaNNaNNaNNaN470.0265.0NaN376.0NaNNaNNaNNaNNaNNaNNaNNaN
1990NaNNaNNaN14545.0NaNNaNNaNNaN507.0311.0NaN478.0NaNNaNNaNNaNNaNNaNNaNNaN
1991NaNNaNNaN14240.0NaNNaNNaNNaN451.0278.0NaN722.0NaNNaNNaNNaNNaNNaNNaNNaN
1992NaNNaNNaN14494.0NaNNaNNaNNaN430.0260.0NaN978.0NaNNaNNaNNaNNaNNaNNaNNaN
1993NaNNaNNaN13819.0NaNNaNNaNNaN503.0291.0NaN1194.0NaNNaNNaNNaNNaNNaNNaNNaN
1994NaN1451.0NaN14379.0NaNNaNNaNNaN597.0351.0NaN1332.0NaNNaNNaNNaNNaNNaNNaNNaN
1995NaN1254.0NaN13277.0NaNNaNNaNNaN549.0351.0NaN1726.0219.0NaNNaNNaNNaNNaNNaNNaN
1996NaN831.0NaN11956.0NaNNaNNaNNaN552.0349.0NaN2063.0339.0NaNNaNNaNNaNNaNNaNNaN
1997NaN1737.0NaN11156.0NaNNaNNaNNaN645.0386.0NaN2363.0407.0NaNNaNNaNNaNNaNNaNNaN
1998NaN1399.0NaN10539.0NaNNaNNaNNaN661.0398.0NaN2690.0478.0225.0NaNNaNNaNNaNNaNNaN
1999NaN1088.0NaN9846.0NaNNaN211.0NaN710.0430.0NaN3238.0561.0257.0NaNNaNNaNNaNNaNNaN
2000NaN1494.0NaN9548.0NaNNaN222.0NaN660.0432.0NaN3783.0691.0320.0NaNNaNNaNNaNNaNNaN
2001NaN3351.0NaN9529.0NaNNaN244.0NaN687.0526.0NaN4642.0822.0439.0NaNNaNNaNNaNNaNNaN
2002NaN4775.0NaN8993.0NaNNaN256.0NaN600.0514.0NaN4883.01182.0438.0NaNNaNNaNNaNNaNNaN
2003NaN3670.0NaN8851.0NaNNaN276.0NaN625.0536.0NaN5080.01465.0448.0NaNNaNNaNNaNNaNNaN
2004NaN3482.0NaN8381.0NaNNaN258.0NaN504.0500.0NaN5359.01621.0515.0NaNNaNNaNNaNNaNNaN
2005NaN3452.0NaN7796.0NaNNaN287.0NaN451.0445.0NaN4953.02266.0502.0NaNNaNNaNNaNNaNNaN
2006NaN3737.0NaN8279.0NaNNaN297.0NaN404.0440.0NaN5145.02839.0530.0NaNNaNNaNNaNNaNNaN
2007NaN3941.0NaN8914.0NaNNaN313.0NaN349.0468.0NaN4925.03028.0526.0NaNNaNNaNNaNNaNNaN
2008955.04028.0219.08511.0NaNNaN317.0NaN344.0400.0NaN4764.03438.0492.0NaNNaNNaNNaNNaNNaN
20091265.04352.0270.07936.0NaNNaN296.0NaN307.0369.0NaN5120.03981.0496.0NaNNaNNaNNaNNaNNaN
2010448.04628.0438.07374.0226.0NaN277.0NaN295.0324.0NaN6200.05164.0504.0NaNNaNNaNNaNNaN258.0

131 rows × 6868 columns

用DataFrame的plot方法绘制几个名字的曲线图:
subset=total_births[['John','Harry','Mary','Marilyn']]
subset.plot(subplots=True,figsize=(12,10),grid=False,title="Number of births per year")
array([<matplotlib.axes._subplots.AxesSubplot object at 0x0000027F80E4F908>,
       <matplotlib.axes._subplots.AxesSubplot object at 0x0000027F80E508D0>,
       <matplotlib.axes._subplots.AxesSubplot object at 0x0000027F80F4FDA0>,
       <matplotlib.axes._subplots.AxesSubplot object at 0x0000027F80E9DEB8>], dtype=object)
plot.show()

这里写图片描述

评估命名多样性的增长

计算最流行的1000个名字所占比例,按year和sex进行聚合并绘图

table=top1000.pivot_table('prop',index='year',columns='sex',aggfunc=sum)
table.plot(title='Sum of table1000.prop by year and sex',yticks=np.linspace(0,1.2,13),xticks=range(1880,2020,10))
plot.show()

这里写图片描述

df=boys[boys.year==2010]
df
namesexbirthsyearprop
yearsex
2010M1676644JacobM2187520100.011523
1676645EthanM1786620100.009411
1676646MichaelM1713320100.009025
1676647JaydenM1703020100.008971
1676648WilliamM1687020100.008887
1676649AlexanderM1663420100.008762
1676650NoahM1628120100.008576
1676651DanielM1567920100.008259
1676652AidenM1540320100.008114
1676653AnthonyM1536420100.008093
1676654JoshuaM1523820100.008027
1676655MasonM1472820100.007758
1676656ChristopherM1413520100.007446
1676657AndrewM1409320100.007424
1676658DavidM1404220100.007397
1676659MatthewM1395420100.007350
1676660LoganM1394320100.007345
1676661ElijahM1373520100.007235
1676662JamesM1371420100.007224
1676663JosephM1365720100.007194
1676664GabrielM1272220100.006701
1676665BenjaminM1228020100.006469
1676666RyanM1188620100.006261
1676667SamuelM1177620100.006203
1676668JacksonM1169320100.006159
1676669JohnM1142420100.006018
1676670NathanM1126920100.005936
1676671JonathanM1102820100.005809
1676672ChristianM1096520100.005776
1676673LiamM1085220100.005716
YairM20120100.000106
1677617TalanM20120100.000106
1677616KeyonM20120100.000106
1677614KaelM20120100.000106
1677613DemarionM20020100.000105
1677618GibsonM20020100.000105
1677619ReaganM20020100.000105
1677620CristoferM19920100.000105
1677621DaylenM19920100.000105
1677622JordonM19920100.000105
1677623DashawnM19820100.000104
1677624MasenM19820100.000104
1677625RowenM19720100.000104
1677629YousefM19720100.000104
1677631ThaddeusM19720100.000104
1677630KadinM19720100.000104
1677628DillanM19720100.000104
1677627ClarenceM19720100.000104
1677626SladeM19620100.000103
1677634ClintonM19620100.000103
1677632SheldonM19620100.000103
1677633KeshawnM19520100.000103
1677636MenachemM19520100.000103
1677637JoziahM19520100.000103
1677635BaileyM19420100.000102
1677638CamiloM19420100.000102
1677639DestinM19420100.000102
1677640JaquanM19420100.000102
1677641JaydanM19420100.000102
1677642MaxtonM19320100.000102

1000 rows × 5 columns

在对prop降序排列后,我们想知道前面有多少个名字的人数加起来才够50%。虽然编写一个for循环确实也能达到目的,但NumPy有一种更聪明的矢量方式。先计算prop的累计和cumsum,然后通过searchsorted方法找出0.5应该被插入在哪个位置才能保证不破坏顺序。

prop_cumsum=df.sort_index(by='prop',ascending=False).prop.cumsum()
C:\Anaconda3\lib\site-packages\ipykernel\__main__.py:1: FutureWarning: by argument to sort_index is deprecated, pls use .sort_values(by=…) if __name__ == ‘__main__’:
prop_cumsum[:10]
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
Name: prop, dtype: float64
prop_cumsum.searchsorted(0.5)
array([116], dtype=int64)
df=boys[boys.year==1900]
in1900=df.sort_index(by='prop',ascending=False).prop.cumsum()
in1900.searchsorted(0.5)+1
C:\Anaconda3\lib\site-packages\ipykernel\__main__.py:2: FutureWarning: by argument to sort_index is deprecated, pls use .sort_values(by=...)
  from ipykernel import kernelapp as app


array([25], dtype=int64)

按这两个字段进行groupby处理,然后用一个函数计算各分组的这个值。

def get_quantile_count(group,q=0.5):
    group=group.sort_index(by='prop',ascending=False)
    return group.prop.cumsum().searchsorted(0.5)[0]+1  #注意这里和书上不一样
diversity=top1000.groupby(['year','sex']).apply(get_quantile_count)
diversity=diversity.unstack('sex')  #依靠Sex入栈操纵,变Series为DataFrame
C:\Anaconda3\lib\site-packages\ipykernel\__main__.py:2: FutureWarning: by argument to sort_index is deprecated, pls use .sort_values(by=...)
  from ipykernel import kernelapp as app

现在,diversity这个DataFrame拥有两个时间序列(每个性别各一个,按年度索引)。

diversity.head()
sexFM
year
18803814
18813814
18823815
18833915
18843916
diversity.plot(title="Number of popular names in top 50%")
plot.show()

这里写图片描述

“最后一个字母”的变革

从name列取出最后一个字母

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)
subtable=table.reindex(columns=[1910,1960,2010],level='year')
subtable.head()
sexFM
year191019602010191019602010
last_letter
a108376.0691247.0670605.0977.05204.028438.0
bNaN694.0450.0411.03912.038859.0
c5.049.0946.0482.015476.023125.0
d6750.03729.02607.022111.0262112.044398.0
e133569.0435013.0313833.028655.0178823.0129012.0

按总出生人数对该表进行规范化处理:

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().astype(float)
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)
plt.show()

这里写图片描述

回到之前创建的那个完整的表,按年度和性别对其进行规范化处理,并在男孩名字中选取几个字母,最后进行转置以便将各个列做成一个时间序列:

letter_prop=table/table.sum().astype(float)
dny_ts=letter_prop.ix[['d','n','y'],'M'].T
dny_ts.head()
last_letterdny
year
18800.0830550.1532130.075760
18810.0832470.1532140.077451
18820.0853400.1495600.077537
18830.0840660.1516460.079144
18840.0861200.1499150.080405

有了这个时间序列的DataFrame之后,就可以通过其plot方法绘制出一张趋势图了:

dny_ts.plot()
plt.show()

这里写图片描述

变成女孩名字的男孩名字(以及相反的情况)

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=table.div(table.sum(1),axis=0)
table.tail()
sexFM
year
20061.0NaN
20071.0NaN
20081.0NaN
20091.0NaN
20101.0NaN

绘制分性别的年度曲线图:

table.plot(style={'M':'k-','F':'k--'})
plt.show()

这里写图片描述

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值