《利用Python进行数据分析》初阶例题分析-2:美国1880-2010年的婴儿名字

文章目录

    • 题目描述
    • 源数据集
    • 数据分析

题目描述

美国社会保障局(SSA)提供了从1880年至现在的婴儿姓名频率的数据。可以使用这些数据做很多事情:
根据给定的名字对婴儿名字随时间的比例进行可视化
确定一个名字的相对排位
确定每年最受欢迎的名字,或者流行程度最高或最低的名字

源数据集

点此获得该系列1-4数据
提取码:if5a

数据分析

加载其中一个数据集,即1880年出生婴儿名字数据集

names1880 = pd.read_csv("datasets/babynames/yob1880.txt",
                        names=["name", "sex", "births"])
names1880

在这里插入图片描述
先将数据集中按性别作为索引,统计1880年男女出生比例
按年份先后顺序,读取数据集文件,将年份添加成新的索引,将这些数据合并显示

names1880.groupby("sex")["births"].sum()

pieces = []
for year in range(1880, 2011):
    path = f"datasets/babynames/yob{year}.txt"
    frame = pd.read_csv(path, names=["name", "sex", "births"])

    # Add a column for the year
    frame["year"] = year
    pieces.append(frame)

# Concatenate everything into a single DataFrame
names = pd.concat(pieces, ignore_index=True)

names

在这里插入图片描述
在这里插入图片描述
将出生的人按年份与性别做成透视表,使用pivot_table()函数创建了一个数据透视表total_births,其中聚合了"births"列,以"year"作为行索引,以"sex"作为列索引,并使用sum函数进行聚合。通过total_births.tail()可以查看数据透视表的最后几行,以了解总出生人数按性别和年份的情况。使用total_births.plot()绘制了一个关于总出生人数按性别和年份的折线图,其中标题为"Total births by sex and year"。

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

在这里插入图片描述
定义了一个名为add_prop的函数,用于在groupby操作中添加一个名为"prop"的新列,该列计算每个组内的出生人数占总出生人数的比例。使用groupby函数按照"year"和"sex"两个列进行分组,并将add_prop函数应用于每个分组。参数group_keys=False用于禁止在结果中包含组键。

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

names

在这里插入图片描述
计算每个分组内出生人数占总出生人数的比例的和,验证数据是否有丢失。

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

在这里插入图片描述
按照年份与性别分组,取得出生的婴儿所求最多的名字前一千排成列表

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

top1000 = top1000.reset_index(drop=True)

top1000.head()

在这里插入图片描述
在这里插入图片描述
按照时间排序将以上数据可视化,以名字为索引,每个名字画一张折线图

boys = top1000[top1000["sex"] == "M"]
girls = top1000[top1000["sex"] == "F"]

total_births = top1000.pivot_table("births", index="year",
                                   columns="name",
                                   aggfunc=sum)

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

在这里插入图片描述
将年份、性别、所占比例做成透视图并作可视化,可以得到这些前1000名取得名字随着时代的变化,这些大众名字概率正在下降。

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

在这里插入图片描述
2010年出生的男孩按取名概率降序排列,并计算累计和,0.5出现在第116个名字,而1900年仅仅出现在24个名字,大众名字确实在减少。下图是1880年到2010年名字概率累计和达到0.5时索引值的变化。

df = boys[boys["year"] == 2010]
df
prop_cumsum = df["prop"].sort_values(ascending=False).cumsum()
prop_cumsum[:10]
prop_cumsum.searchsorted(0.5)
df = boys[boys.year == 1900]
in1900 = df.sort_values("prop", ascending=False).prop.cumsum()
in1900.searchsorted(0.5)
def get_quantile_count(group, q=0.5):
    group = group.sort_values("prop", ascending=False)
    return group.prop.cumsum().searchsorted(q) + 1

diversity = top1000.groupby(["year", "sex"]).apply(get_quantile_count)
diversity = diversity.unstack()
fig = plt.figure()
diversity.head()
diversity.plot(title="Number of popular names in top 50%")

在这里插入图片描述
列举1910,1960,2010三年出生的婴儿名字的最后一个字母的出现次数,并计算其出现的比率可视化。可以看出近些年男婴以n结尾现象占大部分还在急剧增加,女婴以a结尾名字也在逐年增多,以e结尾也占很大一部分,但是在逐年衰减。

def get_last_letter(x):
    return 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()  
subtable.sum()
letter_prop = subtable / subtable.sum()
letter_prop
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)

在这里插入图片描述
取得男婴上述数据,摘取"d", “n”, "y"单独进行观察,发现随着时间进行,d与y短暂出现了峰值,然后快速下降;而n却不断攀升

plt.subplots_adjust(hspace=0.25)
letter_prop = table / table.sum()

dny_ts = letter_prop.loc[["d", "n", "y"], "M"].T
dny_ts.head()
plt.close("all")
fig = plt.figure()
dny_ts.plot()

在这里插入图片描述
在前一千的表格中找到包含"Lesl"的计算其出现总数与出现比例,,可视化可以得到在男生在这些字符出现频率逐年下降,而女生中增加。

all_names = pd.Series(top1000["name"].unique())
lesley_like = all_names[all_names.str.contains("Lesl")]
lesley_like
filtered = top1000[top1000["name"].isin(lesley_like)]
filtered.groupby("name")["births"].sum()
table = filtered.pivot_table("births", index="year",
                             columns="sex", aggfunc="sum")
table = table.div(table.sum(axis="columns"), axis="index")
table.tail()
fig = plt.figure()
table.plot(style={"M": "k-", "F": "k--"})
  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值