利用python进行数据分析第十四章实战三
前言
同样的,本节适用于对利用python进行数据分析这本书代码不是很理解的同学,适合初学者,里面含有代码解析。如果是想看完整的书,可以去 https://zhuanlan.zhihu.com/p/68487640
数据下载
参见我的博客实战一里面的下载问题
美国1880-2010年的婴儿名字
1.看一下1880年的数据并初处理一下
提供了1880-2010年的数据,每个都为一个txt文件。一部分截图如下

看一下文件里面的原数据格式
!type -10 "D:\pycsv\babynames\yob1880.txt"

可见它已经以逗号分隔的形式出现,用read_csv将其加载到dataframe中
import pandas as pd
names1880 =pd.read_csv('D:/pycsv/babynames/yob1880.txt',names=['name', 'sex', 'births'])
names1880
前半部分数据如下

通过聚合性别这一项来看1880年男女各多少人
names1880.groupby('sex').births.sum()
#sum()函数是求和的
#names1880.groupby('sex')['births'].sum()代码意思一样

2.对1880-210年的文件进行dataframe合并
import pandas as pd
years=range(1880,2011)
pieces=[]
columns=['name','sex','births']
for year in years:
path="D:/pycsv/b/babynames/yob"+str(year)+".txt"
frame=pd.read_csv(path,names=columns)
frame['year']=year
pieces.append(frame)#将frame添加到列表pieces中
#所有frame接到一个列表中
pieces
每一个dataframe作为列表的一个元素

再通过concat函数把存在列表pieces中的dataframe纵向拼接
names=pd.concat(pieces,ignore_index=True)
names
concat函数的具体可参考:https://blog.csdn.net/zzpdbk/article/details/79232661
数据的后半部分:

以年为索引,性别为列,出生数为值,统计每年的男女出生总数
total_births=names.pivot_table('births',index='year',columns='sex',aggfunc=sum)
total_births.tail()

画图
total_births.plot(title='Total births by sex and year')

按性别和年份进行分组聚合,每个婴儿名字的占比。插入prop列存占比
def add_prop(group):
group['prop'] = group.births / group.births.sum()
return group
names = names.groupby(['year', 'sex']).apply(add_prop)
names
部分截图

验证一下,每组prop的总和为1
names.groupby(['year','sex']).prop.sum()
部分截图

看每个性别,年份组合的前1000名,
def get_top1000(group):
return group.sort_values(by='births', ascending=False)[:1000]
grouped = names.groupby(['year', 'sex'])
top1000 = grouped.apply(get_top1000)
top1000.reset_index(inplace=True, drop=True)
top1000

分析名字的趋势
首先,将top1000的名字分成男孩和女孩两部分。
boys=top1000[top1000.sex=='M']
girls=top1000[top1000.sex=='F']
按年份和名字形成出生总数的数据透视表
total_births = top1000.pivot_table('births', index='year',columns='name',aggfunc=sum)
total_births.head()

‘John’,‘Harry’,‘Marry’,'Marilyn’名字的趋势
subset=total_births[['John','Harry','Marry','Marilyn']]
subset.plot(subplots=True,figsize=(12,10),grid=False,title='Number of births per year')
plt.show()

计算命名的多样性,如何判断多样性呢,在热门名字的出现程度下降即可意味着其他名字的出现,命名的多样性。所以可以求top1000名字的占比变化趋势
import numpy as np
table = top1000.pivot_table('prop', index='year',columns='sex', aggfunc=sum)
#注意这里是top1000的prop加起来
table

再画图
table.plot(title='Sum of table1000.prop by year and sex',yticks=np.linspace(0, 1.2, 13), xticks=range(1880, 2020, 10))

另一个有趣的趋势是,较早流行的男孩名字已经随着时间的推移变成了女孩子的名字,一个例子是lesley或leslie的名字
计算lesl开头的名字的列表
all_names=pd.Series(top1000.name.unique())
all_names
数据后半部分

包含lesl的
lesley_like=all_names[all_names.str.lower().str.contains('lesl')]
lesley_like

filtered=top1000[top1000.name.isin(lesley_like)]
filtered
#每一年中 男女名字中包含lesl的
部分数据

filtered.groupby('name').births.sum()
#这么多年来这些lesl名字的总和

按性别和年份进行聚合,并在年内进行标准化
table=table.div(table.sum(1),axis=0)
table.tail()

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

书中还有一些分析,如男孩女孩最后一个字母的比例,不过我没有做这个
本篇博客介绍使用Python进行数据分析,以美国1880年至2010年婴儿名字数据为例,展示了数据读取、处理、合并及分析的全过程。包括数据的初步探索、性别出生数统计、名字趋势分析、命名多样性和名字流行度变迁等内容。

2781

被折叠的 条评论
为什么被折叠?



