1880-2010年间全美婴儿姓名

1880-2010年间全美婴儿姓名

!git clone https://github.com/wesm/pydata-book

0 导入相关库

# 基础
import numpy as np # 处理数组
import pandas as pd # 读取数据&&DataFrame
import matplotlib.pyplot as plt # 制图
import seaborn as sns
from matplotlib import rcParams # 定义参数
from matplotlib.cm import rainbow # 配置颜色

%matplotlib inline 
import warnings
warnings.filterwarnings('ignore') # 忽略警告信息
np.set_printoptions(precision=4) # 小数点后
pd.options.display.max_rows = 10 # 最大行数

1 读取文本文件(文件夹、TXT格式)

!ls pydata-book/datasets/babynames  

在这里插入图片描述

!head -n 10 pydata-book/datasets/babynames/yob1880.txt

在这里插入图片描述

性别/名字组合的出生总数

names1880 = pd.read_csv('pydata-book/datasets/babynames/yob1880.txt',
                        names=['name', 'sex', 'births'])
names1880

在这里插入图片描述

names1880.groupby('sex').births.sum()

在这里插入图片描述

years = range(1880, 2011)

pieces = []
columns = ['name', 'sex', 'births']

for year in years:
    path = 'pydata-book/datasets/babynames/yob%d.txt' % year
    frame = pd.read_csv(path, names=columns)

    frame['year'] = year
    pieces.append(frame)

names = pd.concat(pieces, ignore_index=True)

names

在这里插入图片描述

2 数据预处理

聚合
pd.DataFrame.pivot_table

total_births = names.pivot_table('births', index='year',
                                 columns='sex', aggfunc=sum)
total_births

在这里插入图片描述

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

在这里插入图片描述

def add_prop(group):
    group['prop'] = group.births / group.births.sum()
    return group
names = names.groupby(['year', 'sex']).apply(add_prop)
names

在这里插入图片描述

names.groupby(['year', 'sex']).prop.sum()

在这里插入图片描述

def get_top1000(group):
    return group.sort_values(by='births', ascending=False)[:1000]
grouped = names.groupby(['year', 'sex'])
top1000 = grouped.apply(get_top1000)

top1000

在这里插入图片描述

3 分析命名趋势

# 按性别分为两部分
boys = top1000[top1000.sex == 'M']
girls = top1000[top1000.sex == 'F']
# 按year name 统计的总出生透视表
total_births = top1000.pivot_table('births', index='year',
                                   columns='name',
                                   aggfunc=sum)
total_births.info()

在这里插入图片描述

total_births

在这里插入图片描述

subset = total_births[['John', 'Harry', 'Mary', 'Marilyn']]
subset.plot(subplots=True, figsize=(12, 10), grid=False,
            title="Number of births per year")

在这里插入图片描述
观察发现这几个名字目前已然日落西山

4 评估命名多样性的增长

  1. 父母越来越不愿意给小孩起常见的名字
  2. 计算最流行的1000个名字所占的比例

按year & sex去和并绘图
pd.DataFrame.pivot_table
pd.DataFrame.plot
np.linspace

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))

在这里插入图片描述
前1000项的比例降低 -> 名字的多样性增长

3.计算占总出生人数前50%的不同名字的数量
只考虑2010年男孩的名字

df2010 = boys[boys.year == 2010]
df2010

在这里插入图片描述

pd.DataFrame.sort_values
pd.DataFrame.cumsum # 累计和
pd.Series.searchsorted

prop_cumsum2010 = df2010.sort_values(by='prop', ascending=False).prop.cumsum()

prop_cumsum2010

在这里插入图片描述

prop_cumsum2010.values.searchsorted(0.5)

在这里插入图片描述
数组索引从0开始(即116+1)

df1900 = boys[boys.year == 1900]
prop_cumsum1900 = df1900

boys[boys.year == 1900].sort_values(by='prop', ascending=False).prop.cumsum().values.searchsorted(0.5) + 1

对所有year/sex组合执行计算
按year/sex字段进行groupby处理,然后用一个函数计算各分组的值

def get_quantile_count(group, q=0.5):
    group = group.sort_values(by='prop', ascending=False)
    return group.prop.cumsum().values.searchsorted(q) + 1

diversity = top1000.groupby(['year', 'sex']).apply(get_quantile_count)
diversity

在这里插入图片描述

pd.DataFrame.unstack # 反堆栈

diversity.unstack('sex')

在这里插入图片描述

diversity.unstack('sex').plot(title='Number of popular names in top 50%')

在这里插入图片描述
观察图可发现女孩名字的多样性总比男孩高,而且越来越高

5 “最后一个字母”的变革

last_letters = names.name.map(lambda x: x[-1])

last_letters.name = 'last_letter'

table = names.pivot_table('births', index=last_letters, columns=['sex', 'year'], aggfunc=sum)
table

在这里插入图片描述

选出具有一定代表性的三年

subtable = table.reindex(columns=[1910, 1960, 2010], level='year')
subtable

在这里插入图片描述

规范化处理 -> 计算出各性别各末字母占总出生人数的比例

subtable.sum()

在这里插入图片描述

letter_prop = subtable / subtable.sum()
letter_prop

在这里插入图片描述

各年度各性别条形图
pd.DataFrame.plot

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.tight_layout() # 最佳

在这里插入图片描述
观察图可知,20世纪60年代开始,以字母为’n’结尾的男孩名字出现了显著增长

按照年度和性别对table进行规范化处理,并在男孩名字中选取几个字母
进行转置后将各个列做成一个时间序列

letter_prop = table / table.sum()
letter_prop

在这里插入图片描述

letter_prop.loc[['d', 'n', 'y'], 'M']

在这里插入图片描述

letter_prop.loc[['d', 'n', 'y'], 'M'].T

在这里插入图片描述

letter_prop.loc[['d', 'n', 'y'], 'M'].T.plot()

在这里插入图片描述

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

找出以’lesl’开头的名字
pd.Series.unique
str.contains

all_names = pd.Series(top1000.name.unique())
lesl_like = all_names[all_names.str.lower().str.contains('lesl')]
lesl_like

在这里插入图片描述

利用lesl_like过滤其他名字,并按名字分组计算出生数以查看相对频率
pd.Series.isin
pd.Series.sum

filtered = top1000[top1000.name.isin(lesl_like)]
filtered.groupby('name').births.sum()

在这里插入图片描述

按性别和年度进行聚合,并按年度进行规范化处理
pd.DataFrame.div
pd.DataFrame.sum

table = filtered.pivot_table('births', index='year', columns='sex', aggfunc='sum')
table = table.div(table.sum(1), axis=0)
table

在这里插入图片描述

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

在这里插入图片描述

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值