这份数据包含了从1880到2010年间的婴儿名字频率数据,其数据形式是多个txt文件,且用逗号分隔,可以用pandas.read_csv将其加载到DataFrame中,并且用pandas.concat将所有数据都组装到一个DataFrame。
years=range(1880,2011)
pieces=[]
columns=['name','sex','births']
for year in years:
path='yob%d.txt'%year
frame=pd.read_csv(path,names=columns)
frame['year']=year
pieces.append(frame)
names=pd.concat(pieces,ignore_index=True)
total_births=names.pivot_table('births',index='year',columns='sex',aggfunc=sum)
def add_prop(group):
births=group.births.astype(float)
group['prop']=births/births.sum()
return group
names=names.groupby(['year','sex']).apply(add_prop)
在执行这样的分组处理时,一般都会做一些有效性检查,比如验证所有分组的prop的总和是否为1
np.allcolse(names.groupby(['year','sex']).prop.sum(),1)
结果为:True
(1)需要取出该数据的一个子集:每对sex/year组合的前1000个名字:
def get_top1000(group):
return group.sort_values(by='births',ascending=False)[:1000]
grouped=names.groupby(['year','sex'])
top1000=grouped.apply(get_top1000)
(2)分析命名的趋势:
先是生成一张按year和name统计的总出生人数透视表:
total_births=top1000.pivot_table('births',index='year',columns='sex',aggfunc=sum)
用DataFrame的plot方法绘制几个名字的曲线图:
subset=total_births[['John','Harry','Marry','Marilyn']]
subset.plot(subplots=True,figsize=(12,10),grid=False)
plt.show()
从这张图中可以看出这两个之前比较流行的名字随着时间的流逝已经风光不再了,所以我们需要来评估命名多样的增长。
计算最流行的1000个名字所占的比例,按year和sex进行聚合并绘图:
table=top1000.pivot_table('prop',index='year',columns='sex',aggfunc=sum)
table.plot(yticks=np.linspace(0,1.2,13),xticks=range(1880,2020,10))
plt.show()
表明前1000项的名字比例在下降,名字的多样性在增加。