使用Python Pandas、Matplotlib和Seaborn探索收入模式

TL;DR · AI 摘要
通过Python的pandas、matplotlib和seaborn分析美国人口普查数据,揭示年龄、教育、性别等因素对收入的影响,发现教育水平与收入呈强正相关,而性别差距依然显著。
核心要点
- 使用pandas处理Adult Census Income Dataset时,需清理缺失值和异常标签(如'?')以确保分析准确性。
- Seaborn的箱线图显示,拥有博士学位的人群平均收入显著高于其他教育水平群体,中位数超过5万美元。
- Matplotlib绘制的散点图表明,年龄在25至45岁之间的人群收入增长最快,之后趋于平稳。
结构提纲
按章节快速跳转。
- §引言
文章探讨如何利用Python分析收入影响因素,强调数据驱动洞察的重要性。
- ·项目目标
本项目旨在通过探索性数据分析揭示影响收入的关键变量及其关系。
使用来自UCI的Adult Census Income Dataset,包含年龄、教育、职业等字段。
安装并导入pandas、matplotlib和seaborn用于数据处理与可视化。
使用pandas读取CSV文件,并进行基本统计描述和缺失值检查。
通过seaborn绘制箱线图和散点图,展示教育、年龄与收入的关系。
思维导图
用一张图看清主题之间的关系。
查看大纲文本(无障碍 / 无 JS 友好)
- 收入模式探索
- 数据来源
- Adult Census Income Dataset
- UCI Machine Learning Repository
- 分析工具
- pandas
- matplotlib
- seaborn
- 关键变量
- 教育水平
- 年龄
- 性别
- 职业
- 可视化方法
- 箱线图
- 散点图
- 热力图
金句 / Highlights
值得收藏与分享的关键句。
教育水平与收入高度相关:博士学历人群的平均收入远高于高中以下学历者。
尽管数据来自1990年代,但性别收入差距仍明显,男性平均收入比女性高出约20%。
使用pandas处理分类变量时,应将'?'替换为NaN以便后续清洗和建模。
Seaborn的热力图可有效展示不同职业类别与收入分布之间的关联模式。
谈到收入和赚钱,我们往往将成功归因于努力工作和聪明才智。有时,我们也只是假设某些人运气好,尽管他们的教育水平较低或缺乏专业技能,却依然能在职业上取得成功并获得可观的收入。然而,真相其实介于这两个极端之间。的确,有些人确实靠运气在年轻时就成为百万富翁,但我们也能看到许多人通过不懈努力攀登职业阶梯,在需要的地方付出额外的努力来提升专业能力,从而增加收入。
在本文中,我们将使用 Python 探索收入与不同因素之间的关系,例如年龄、性别、职业、教育程度等。尽管在当今时代,绘制图表和提取洞察变得非常容易,但了解如何结合人类分析与计算能力从原始数据中提取洞察仍然非常重要。这需要具备一定的 Python 基础知识。通过使用 Python 及其强大的数据处理库,我们将识别出一些可预测的模式,帮助我们根据所使用的数据集,深入理解影响收入的一般性因素!
项目介绍
在本项目中,我们将借助 Python 深入分析一个人口普查数据集,并使用 pandas、matplotlib 和 seaborn 等强大的数据分析库来揭示收入模式。通过数据清洗工具、数据可视化和探索性分析,我们将把原始数据转化为有价值的见解,了解哪些因素影响收入以及其影响程度。这是一个适合初学者到中级水平的 Python 编程项目,要求你掌握基本的 Python 知识,特别是如何从不同库中导入并使用函数进行数据探索与分析。
数据集说明
在本项目中,我们将使用 Adult Census Income Dataset,这是一个源自美国人口普查数据的真实世界数据集。虽然该数据集可追溯至 20 世纪 90 年代,但我们仍可以利用它来分析收入模式,尽管过去 30 年间情况已发生显著变化,尤其是在曾经非常突出的性别差距方面。该数据集包含人口统计和就业相关信息,如个人年龄、职业、教育水平、婚姻状况、性别、每周工作小时数等,其中大部分信息对我们的项目目标具有重要价值。该数据集公开可用,常用于教学和研究项目。
数据集:Adult Census Income Dataset
来源:UCI 机器学习仓库(CC BY 4.0)
原始数据来自美国人口普查局数据库。
现在,让我们开始吧!
配置编程环境
在开始之前,请确保你的编程环境已正确设置。为此,请确认系统中已安装 Python,并打开你喜欢的编程 IDE。我将使用 PyCharm,因其对初学者友好且包管理便捷。
首先,创建一个名为“Adults Income Pattern Analysis”的新项目,并创建一个名为 main.py 的 Python 文件。所有代码都将在此文件中编写。
安装并导入相关库
接下来,安装所需的库或 Python 包。我们将使用以下库进行数据探索和分析:
- Pandas – 这是最流行的库之一,用于处理表格数据(如 CSV 文件)
- Matplotlib – 这个 Python 库允许创建图表、图形和其他数据可视化内容
- Seaborn – 基于 matplotlib 构建的库,极大扩展了数据可视化功能,使图表更易于制作且更具美观性
我们将在 PyCharm 的终端中安装上述库(也可搜索适用于你所用 IDE 的安装方法):
pip install pandas matplotlib seaborn安装完成后,我们将这些库导入到 main.py 文件中:
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns加载数据集与基础分析
现在,我们将数据集加载到名为 df 的变量中,作为 DataFrame。这是使用 pandas 标准方式加载数据集的方法:
df = pd.read_csv("https://huggingface.co/api/resolve-cache/datasets/scikit-learn/adult-census-income/fbeef6ec0e6fd88a5028b94683144000a6b380d5/adult.csv?%2Fdatasets%2Fscikit-learn%2Fadult-census-income%2Fresolve%2Fmain%2Fadult.csv=&etag=%225cf74ede1a6de37d85c96a61d30819a694dee749%22")
print(df.head())
df.head()(作者图片)
如图所示,我们首先从之前提供的 URL 加载了数据集,然后使用 df.head() 函数打印出数据集的前五行,以了解其结构。我们可以看到一些列名:age(年龄)、workclass(工作类别)、fnlweight、hours.per.week(每周工作小时数)、native.country(原籍国家)和 income(收入)。这里可以看到 fnlweight 和 hours.per.week 之间有虚线,表明还存在其他列,但由于输出屏幕空间有限而未能完全显示。这个问题可以通过几行代码解决(我们稍后会详细介绍)。
现在,让我们看看数据集有多少行和列。我们将使用 df.shape 命令来输出行数和列数,从而了解我们正在处理的数据集的规模。
print(df.shape)
df.shape(作者供图)
最后,让我们获取列的详细信息,包括它们存储的数据类型:
print(df.info())
df.info()(作者供图)
从上述结果可以看出,我们的数据集包含分类特征和数值特征,具体列名如下:
| 列名 | 含义 | | --- | --- | | age | 个体年龄(单位:年) | | workclass | 就业类型/工作领域:Private → 私营公司员工;Self-emp-not-inc → 自雇(非公司注册);Government → 政府雇员;Without-pay → 无报酬工作者 | | fnlwgt | 美国人口普查局分配的最终抽样权重 | | education | 最高教育程度:Bachelors(学士)、HS-grad(高中毕业)、Masters(硕士)、Doctorate(博士) | | education.num | 教育程度的数值表示:高中 → 9;学士 → 13;硕士 → 14 | | marital.status | 个人婚姻状况 | | occupation | 职业类型/专业 | | relationship | 家庭中的关系状态:Husband(丈夫)、Wife(妻子)、Own-child(子女)、Not-in-family(非家庭成员) | | race | 种族类别 | | sex | 性别 | | capital.gain | 投资/资产带来的收益 | | capital.loss | 投资/资产造成的损失 | | hours.per.week | 每周平均工作小时数 | | native.country | 出生国家 | | income | 收入类别(目标变量),通常为:<=50K 或 >50K |
现在,让我们显示前5行及其完整列。运行以下代码以不截断的方式查看前5行:
print(df.head().to_string())
df.head() 完整行(作者供图)

df.head() 完整行(作者供图)
数据清洗
现在我们已经完成了对数据整体情况的初步了解,可以进入分析阶段了。但在那之前,非常重要的一点是确保我们的数据是干净且有价值的,以便从中得出有意义的洞察;换句话说,我们不希望数据存在不准确或缺失值的情况,因为这可能会扭曲分析指标。因此,我们将通过删除含有缺失值的行来清洗数据。
我们将使用 pandas 的 replace() 函数将问号("?")替换为 NA,并使用 dropna() 函数删除数据框中包含缺失值的行。任何缺少职业、教育信息等的行都将被从数据框中删除。我们也可以通过以下代码看到有多少行被移除:
print("清洗前:", len(df))
df = df.replace("?", pd.NA).dropna()
print("清洗后:", len(df))
数据清洗(作者供图)
如图所示,经过清洗后,我们的数据集从最初的 32,561 行减少到仅剩 30,162 行。
收入总体分析
让我们从这里开始数据分析!我们知道收入标准存储在 income 列中,其值要么大于 50k,要么小于等于 50k。另外请注意,这是 1994 年的人口普查数据,因此不要对这些数字感到惊讶!
让我们可视化收入数据:
# 收入图表
sns.countplot(x="income", data=df)
plt.show()我们使用 Python 的 seaborn 库创建了一个收入计数图。

收入计数图(作者供图)
从上图可以看出,大多数人的收入低于 50k,而只有少数人收入超过 50k。该图表不仅揭示了收入分布的不平衡性,还反映了 20 世纪 90 年代初美国的经济结构,在当时 $50k 被认为是一个相对较高的年薪水平。
教育与收入关系分析
现在,让我们看看教育水平如何影响收入。这一点尤其值得关注,因为普遍认为受教育程度越高的人往往比教育程度较低者赚得更多。让我们检查一下数据是否支持这一观点:
# 教育与收入关系
result = df.groupby("education")["income"].value_counts()
print(result)
教育与收入关系(作者供图)
# 教育与收入关系
result = df.groupby("education")["income"].value_counts().unstack()
# 绘图
result.plot(kind="bar", figsize=(12,6))
# 标签和标题
plt.title("教育 vs 收入")
plt.xlabel("教育水平")
plt.ylabel("数量")
plt.xticks(rotation=45)
# 显示图表
plt.show()
教育 vs 收入(作者供图)
上述结果表明,更高的教育水平通常是导致更高收入的一个重要因素。尽管无法直接从 pandas 的 groupby() 结果中直观看出这种趋势,但我们使用 seaborn 的计数图来展示不同教育水平如何影响个体的收入范围。
由此可见:
- 教育水平低于“部分大学”(some college)的人群中,收入超过 50k 的人数极少。
- 更高的教育水平与更高的收入高度相关,大多数收入超过 50k 的人拥有学士、硕士、大学学位等学历。
- 高中学历在低收入群体中占主导地位,这可以从最高的蓝色柱状图看出。
- 专业学位和博士学位的橙色柱状图高于蓝色柱状图,表明这些学历人群中收入超过 50k 的比例更高,这符合逻辑,因为技术专长通常会获得更高的回报。
- 有趣的是,在高学历人群中,并非所有人都收入超过 50k,这意味着除了教育水平之外,还有其他重要因素影响收入。让我们进一步分析其他列!
收入与每周工作时数的关系分析
现在我们来看看努力工作是否真的有回报,即工作时间更长的人是否倾向于获得更高的收入?接下来的几行代码使用箱线图来分析收入与每周工作时数之间是否存在某种关系:
# 显示图表
sns.boxplot(x="income", y="hours.per.week", data=df)
plt.show()
从上面的箱线图可以看出,收入超过 50k 的人群具有更高的中位数、更大的分布范围以及更多长时间工作的个体。这支持了我们的假设:是的,每周工作时间更长的人通常收入也更高。但另一方面,我们也注意到左侧箱线图中的异常值,表明确实存在一些每周工作超过 70 小时但仍收入低于 50k 的人。这意味着虽然高收入者通常工作时间较长,但仅靠长时间工作并不能保证高薪。除了教育水平和每周工作时数之外,还有其他因素影响收入,因此我们继续分析下一个参数!
收入与性别的关系分析
我们知道,关于性别差距以及在同一职位上男性和女性员工之间的薪酬歧视问题一直备受关注。那么在 20 世纪 90 年代是否也存在这种情况?如果存在,其程度如何?
我们借助条形图来可视化这一情况:
result = df.groupby("sex")["income"].value_counts().unstack()
# 绘制图形并自定义颜色
ax = result.plot(
kind="bar",
figsize=(10,6),
color=["skyblue", "blue"]
)
# 在条形图上添加标签
for container in ax.containers:
ax.bar_label(container)
# 添加标题和标签
plt.title("按性别划分的收入分布")
plt.xlabel("性别")
plt.ylabel("人数")
plt.xticks(rotation=0)
# 显示图形
plt.show()
按性别划分的收入分布(作者供图)
从上述按性别划分的收入分布图可以看出,收入超过 50k 的男性明显多于女性。此外,数据集中大多数女性的收入都在 50k 以下。我们可以得出结论:高收入男性的比例高于高收入女性。
收入与工作类别(Workclass)的关系分析
现在,我们进一步分析不同工作类别下的收入差异。为此,我们首先查看不同的工作类别,然后创建条形图进行可视化分析。
print(df["workclass"].unique())
# 选择主要的工作类别
top_workclasses = df["workclass"].value_counts().head(7).index
filtered_df = df[df["workclass"].isin(top_workclasses)]
# 创建图表
plt.figure(figsize=(10,6))
sns.countplot(
data=filtered_df,
x="workclass",
hue="income"
)
# 添加标题和标签
plt.title("不同工作类别中的收入分布")
plt.xlabel("工作类别")
plt.ylabel("人数")
plt.xticks(rotation=15)
plt.show()
不同工作类别中的收入分布(作者供图)
上述条形图显示,数据集中大多数人从事私营部门工作,使其成为最主要的就业类别。在几乎所有工作类别中,收入低于 50k 的人数都显著高于收入超过 50k 的人数。自营企业雇员(Self-emp-inc)相比某些政府机构显示出相对较高的高收入比例。
收入与职业(Occupation)的关系分析
现在,我们通过一个简单的打印语句来看看职业如何影响收入。
result = df[df["income"] == ">50K"]["occupation"].value_counts().head(10)
print(result)
职业与收入(作者供图)
在上面的代码中,我们提取了收入超过 50k 的前 10 种职业。从输出结果可以看出,收入最高的职业是“高管/经理”(exec managerial),其次是“专业技术人员”(prof speciality)等。这说明高管职位、专业技术岗位和具备特殊技能的工作具有更高的收入潜力。
收入与年龄的关系分析
接下来,我们看看年龄如何影响收入。
# 创建图形
plt.figure(figsize=(10,6))
# 箱线图
sns.boxplot(
x="income",
y="age",
data=df
)
# 添加标题和标签
plt.title("年龄与收入的关系模式")
plt.xlabel("收入类别")
plt.ylabel("年龄")
# 显示图形
plt.show()
年龄与收入的关系模式(作者供图)
如上图所示,我们创建了一个简单的图表,包含两个方框,一个表示收入低于 50,000 美元的类别,另一个表示收入高于 50,000 美元的类别。从图表中可以看出,年轻人大多属于收入低于 50,000 美元的群体,该类别中也有少数年龄较大的异常值。我们还可以看到,高收入人群的中位年龄明显更高,这表明收入往往随着年龄和经验的增长而增加。这反映了职业发展、工作经验和资历通常会随着时间推移带来更高的薪资。
主要发现与结论
在本文中,我们深入分析了 1994 年美国人口普查数据集,以探究收入在不同因素(如年龄、性别、职业、工作类别、每周工作小时数等)下的趋势。主要发现如下:
- 绝大多数人口属于低收入群体
- 教育水平通常会提高获得高收入的概率
- 工作时长有一定影响,但作用较小;每周工作时间更长并不保证收入更高!
- 职业是影响高收入的重要因素之一;某些特定职位本身就足以带来更高的收入!
- 收入通常随年龄增长而上升。
我们使用了 Python 中的 pandas、matplotlib 和 seaborn 不仅对数据进行了清洗,还借助图表和可视化手段进行了分析。通过本次分析可以得出结论:收入并非由单一因素决定,而是教育、职业、经验和机遇等多种因素共同作用的结果!