初次接触数据分析,你可能会觉得它很复杂,脑海里浮现出大型数据库、高深数学和复杂的机器学习算法。
但许多实用的数据分析任务,起点其实简单得多:加载一份数据集,针对它提出问题,再用 Python 找出答案。
本教程将带你用 Python 和 pandas 搭建一个简单的数据分析器。我们会使用一份虚构的学生成绩数据集,学习如何加载数据、查看数据、计算统计量、筛选记录、分组汇总,并绘制一张基础图表。
学完之后,你将拥有一个可复用的基础框架,用来分析各种类型的 CSV 数据集。
准备工作
开始本教程之前,你需要具备一些基础的 Python 技能和工具。不需要有高级编程或数据分析经验,但应当熟悉以下内容:
- Python 变量和基本数据类型,比如字符串和数字。
- 导入库和调用函数。
- 使用列表以及对数据的基本操作。
如果你是 Python 新手,建议先掌握这些基础知识再继续。想深入学习的话,可以参考这门交互式 Python 课程。
另外,请确保已安装以下内容:
- Python:Python 3 或兼容的 Python 环境。
- pandas:用于加载、筛选、分组和分析数据的 Python 库。
- Matplotlib:用于创建可视化的库。
- 代码编辑器或 IDE:比如 VS Code、PyCharm 或简单的文本编辑器,并能访问终端。
在终端中运行以下命令即可安装 pandas 和 Matplotlib:
pip install pandas matplotlib
你还需要准备一个文件夹,用来存放 Python 脚本和本教程中要创建的 students.csv 数据集。
一切就绪后,就可以开始用 Python 分析数据了!
本教程内容:
- 环境搭建
- 创建数据集
- 用 Pandas 加载数据集
- 探索数据
- 计算基本统计量
- 筛选数据
- 查找特定学生
- 数据分组
- 分析学习时间
- 创建可视化图表
- 构建完整分析器
- 让分析器更易复用
- 处理缺失数据
- 导出结果
- 常见错误及避免方法
- 下一步学习方向
- 结语
环境搭建
安装 pandas
如果还没安装 pandas,打开终端运行:
pip install pandas matplotlib
数据分析用 pandas,简单可视化用 Matplotlib。
可以用下面的命令确认是否安装成功:
import pandas as pd
import matplotlib.pyplot as plt
print(pd.__version__)
如果 Python 能打印出版本号,就说明环境没问题了。
创建数据集
创建 CSV 文件
我们先创建一个名为 students.csv 的文件,并写入一些数据。
这里使用的数据集是虚构的,包含 12 条学生记录,覆盖 9 到 12 年级。每一行代表一名学生,每一列描述一个属性:
name:学生的名字。grade:学生当前所在年级。study_hours:学生的学习时长(小时)。attendance:学生的出勤率。score:学生的考试分数,按 0–100 计。
例如,Ava 读 9 年级,学习了 4.5 小时,出勤率 95%,考试得分 82。借助这些样本记录,我们可以探讨一些问题,比如学习时长是否与考试成绩相关,以及各年级的平均分有何差异。
由于数据是虚构的、样本量也小,我们观察到的任何规律都只是示意性的,不能当作关于学生群体的证据。
不过,这些数据足以支撑几项有用的分析。数据如下:
name,grade,study_hours,attendance,score
Ava,9,4.5,95,82
Liam,9,6.0,98,91
Sophia,10,3.5,89,76
Noah,10,7.0,99,94
Emma,11,5.5,93,88
Oliver,11,8.0,97,96
Mia,12,4.0,91,79
Ethan,12,6.5,96,90
Isabella,9,7.5,100,97
Lucas,10,2.5,85,68
Amelia,11,6.0,94,92
James,12,5.0,90,84
用 Pandas 加载数据集
读取 CSV 文件
首先在 Python 程序中导入 pandas:
import pandas as pd
然后加载 CSV 文件:
data = pd.read_csv("students.csv")
read_csv() 函数读取 CSV 文件,并将其转换为 pandas DataFrame。
DataFrame 是一种类似表格的数据结构,包含行和列。你可以把它看作一个可编程的电子表格。
下面显示数据集:
print(data)
你应该能在终端里看到打印出来的学生记录。
探索数据
分析数据集之前,先弄清楚手头的数据是什么样,会很有帮助。
查看前几行
head() 方法会显示前五行:
print(data.head())
你也可以指定需要的行数:
print(data.head(3))
检查数据集大小
用 shape 查看行数和列数:
print(data.shape)
结果将是:
(12, 5)
也就是说,我们的数据集包含12行5列。
查看列名
可以用下面的方式查看列名:
print(data.columns)
当你需要在程序后续引用列时,这个功能很有用。
检查数据类型
用 info() 查看每一列的信息:
data.info()
这能帮你判断各列中存放的是整数、小数、文本还是其他类型的数据。
计算基本统计量
用 Pandas 计算统计量很方便,无需手动编写数学公式。
求平均分
可以用下面的方法计算平均分:
average_score = data["score"].mean()
print(f"Average score: {average_score:.2f}")
mean() 方法用于计算算术平均值。
:.2f 格式化告诉 Python 将结果显示为两位小数。
查找最高分和最低分
使用 max() 和 min():
highest_score = data["score"].max()
lowest_score = data["score"].min()
print(f"Highest score: {highest_score}")
print(f"Lowest score: {lowest_score}")
你也可以求中位数:
median_score = data["score"].median()
print(f"Median score: {median_score}")
中位数是分数排序后位于中间的那个值。
生成统计摘要
Pandas 还提供了便捷的 describe() 方法:
print(data["score"].describe())
这会生成如下统计信息:
- 计数
- 均值
- 标准差
- 最小值
- 第25百分位数
- 中位数
- 第75百分位数
- 最大值
你可以为所有数值列生成汇总:
print(data.describe())
探索陌生数据集时,这往往是你最先用到的命令之一。
筛选数据
pandas 最实用的功能之一,就是能按条件选取行。
找出高分学生
假设我们要找出得分不低于 90 分的学生:
high_scores = data[data["score"] >= 90]
print(high_scores)
表达式:
data["score"] >= 90
这会为每一行生成一个布尔条件。Pandas 随后只保留条件为 True 的行。
找出学习时间超过五小时的学生
用学习时长也能做同样的筛选:
frequent_studiers = data[data["study_hours"] > 5]
print(frequent_studiers)
也可以组合多个条件。
例如,假设我们要找学习时间超过五小时、出勤率高于95%的学生:
students = data[
(data["study_hours"] > 5) &
(data["attendance"] > 95)
]
print(students)
在 pandas 中组合条件时,用 & 表示 AND,用 | 表示 OR。每个条件都要用括号括起来。
查找特定学生
使用 idxmax()
有时你想要的不仅是最高值,还想知道哪条记录包含这个值。
例如:
top_student_index = data["score"].idxmax()
top_student = data.loc[top_student_index]
print(top_student)
idxmax() 返回最大值所在行的索引。
学习时长也可以同样处理:
most_studious_index = data["study_hours"].idxmax()
most_studious_student = data.loc[most_studious_index]
print(most_studious_student)
这样就能把统计结果关联回原始记录。
数据分组
当数据集包含分类时,分组会特别有用。
在我们的数据集中,学生分属不同年级。
各年级平均分
我们可以计算每个年级的平均分:
average_by_grade = data.groupby("grade")["score"].mean()
print(average_by_grade)
这告诉我们各年级的平均分差异。
我们可以让输出更易读:
average_by_grade = (
data.groupby("grade")["score"]
.mean()
.round(2)
)
print(average_by_grade)
多项统计
你可以一次计算多项统计数据:
grade_summary = data.groupby("grade")["score"].agg(
["mean", "min", "max", "count"]
)
print(grade_summary)
这样会为每个年级生成一份汇总,包含平均分、最低分、最高分和学生人数。
分析学习时间
我们还可以考察学习时长与成绩之间的关系。
计算相关性
Pandas 提供了 corr() 方法:
correlation = data["study_hours"].corr(data["score"])
print(f"Correlation: {correlation:.2f}")
相关系数的取值范围通常在 -1 到 1 之间。
数值越接近 1,说明正线性关系越强;越接近 -1,说明负线性关系越强。数值接近 0 则表示几乎没有线性关系。
不过,相关性并不能证明一个变量导致了另一个变量。例如,即使这份数据集中学习时长与分数存在相关性,也不能证明多学习直接带来了更高分数。
创建可视化
数字固然有用,但可视化能让规律更容易被识别。
创建散点图
下面我们创建一个散点图,展示学习时长与考试分数:
import matplotlib.pyplot as plt
plt.scatter(data["study_hours"], data["score"])
plt.xlabel("Study Hours")
plt.ylabel("Test Score")
plt.title("Study Hours vs. Test Scores")
plt.show()
每个点代表一名学生。
x 轴表示学习时长,y 轴表示考试分数。
你可以观察一下,随着学习时间增加,这些点是否整体呈上升趋势。
正确的图表应该是这样的:

创建柱状图
我们还可以把每个年级的平均分可视化:
average_by_grade = data.groupby("grade")["score"].mean()
average_by_grade.plot(kind="bar")
plt.xlabel("Grade")
plt.ylabel("Average Score")
plt.title("Average Score by Grade")
plt.show()
柱状图能更直观地比较各组之间的平均值。
柱状图大致应呈现如下效果:
构建完整分析器
接下来,我们把核心思路整合到一个程序里。
import pandas as pd
import matplotlib.pyplot as plt
# Load the dataset
data = pd.read_csv("students.csv")
# Basic information
print("Dataset shape:")
print(data.shape)
print("\nFirst five rows:")
print(data.head())
# Score statistics
average_score = data["score"].mean()
median_score = data["score"].median()
highest_score = data["score"].max()
lowest_score = data["score"].min()
print("\nScore Statistics")
print(f"Average: {average_score:.2f}")
print(f"Median: {median_score:.2f}")
print(f"Highest: {highest_score}")
print(f"Lowest: {lowest_score}")
# Students with scores of 90 or higher
high_scores = data[data["score"] >= 90]
print("\nStudents with scores of 90 or higher:")
print(high_scores[["name", "score"]])
# Average score by grade
average_by_grade = (
data.groupby("grade")["score"]
.mean()
.round(2)
)
print("\nAverage Score by Grade:")
print(average_by_grade)
# Study hours and score correlation
correlation = data["study_hours"].corr(data["score"])
print(f"\nStudy Hours vs. Score Correlation: {correlation:.2f}")
# Scatter plot
plt.scatter(data["study_hours"], data["score"])
plt.xlabel("Study Hours")
plt.ylabel("Test Score")
plt.title("Study Hours vs. Test Scores")
plt.show()
现在这个程序已经能完成一个小而完整的数据分析工作流。
让分析器更易复用
下一步很自然的做法,是把重复操作封装成函数。
创建分析函数
与其把所有代码都直接写在主程序里,不如创建一个函数:
def analyze_scores(data):
average = data["score"].mean()
median = data["score"].median()
highest = data["score"].max()
lowest = data["score"].min()
print(f"Average score: {average:.2f}")
print(f"Median score: {median:.2f}")
print(f"Highest score: {highest}")
print(f"Lowest score: {lowest}")
然后这样调用:
analyze_scores(data)
这样代码更容易复用到其他 DataFrame 上。
为成绩最好的学生创建函数
我们还可以创建一个函数,返回得分最高的学生:
def get_top_students(data, minimum_score=90):
return data[data["score"] >= minimum_score][
["name", "grade", "score"]
]
现在可以随时调整阈值:
print(get_top_students(data, 95))
当分析器功能不断扩展时,这类函数会变得尤为重要。
处理缺失数据
真实数据集很少像示例中那样干净整洁,你有时会遇到缺失值。
可以用以下方式检查缺失值:
print(data.isnull().sum())
这能告诉你每一列有多少个缺失值。
例如,你可以用下面的方式删除包含缺失值的行:
clean_data = data.dropna()
或者,根据数据集和缺失值的含义,你也可以选择替换缺失值:
data["score"] = data["score"].fillna(data["score"].mean())
不要一遇到缺失值就用平均值填补。具体怎么处理,要看缺失数据代表什么、你想分析什么。
导出结果
分析完数据集后,你可能想保存结果。
例如:
average_by_grade.to_csv("average_scores_by_grade.csv")
你也可以保存筛选后的记录:
high_scores.to_csv("high_scoring_students.csv", index=False)
index=False 参数的作用是阻止 pandas 把 DataFrame 的索引作为额外一列写入。
常见错误及规避方法
忘记导入库
务必先导入所需的库:
import pandas as pd
import matplotlib.pyplot as plt
否则,Python 就不知道 pd 或 plt 指的是什么。
使用了错误的列名
列名必须与数据集中的列名一致。
例如,如果列名是 study_hours,下面这样写就不会生效:
data["study time"]
你随时可以这样查看实际的列名:
print(data.columns)
混淆相关性与因果关系
相关性可以揭示变量之间的关系,但并不能证明一个变量导致了另一个变量。
处理规模更大、更复杂的数据集时,这一区别愈发重要。
未理解数据就急于分析
人们往往忍不住立刻开始计算统计量,但应先检查数据集。
常用的起步命令包括:
data.head()
data.shape
data.info()
data.describe()
data.isnull().sum()
了解数据的结构和质量,有助于避免得出错误结论。
接下来可以做什么
你构建的分析器刻意保持简单,但同样的工作流可以套用到规模大得多的数据集上。
你可以把它扩展到:
- 分析销售数据
- 跟踪网站流量
- 研究问卷回答
- 分析营销活动
- 考察体育统计数据
- 探索金融数据集
- 跟踪应用或客户数据
你也可以加入更高级的功能,比如交互式图表、命令行参数、自动化报告或机器学习模型。
例如,与其把 CSV 文件名写死在代码里,不如让用户自己指定:
filename = input("Enter the CSV filename: ")
data = pd.read_csv(filename)
print(data.head())
现在,同一个程序可以分析不同的 CSV 文件了。
最后总结
入门数据处理并不需要复杂的算法。只要掌握 Python、pandas,再加上一个规模不大的数据集,你就能做出有价值的分析。
本教程中,你学会了如何:
- 用 pandas 加载 CSV 数据
- 浏览 DataFrame
- 计算统计量
- 筛选行
- 查找特定记录
- 对数据分组
- 计算相关性
- 创建可视化图表
- 处理缺失值
- 导出分析结果
- 用函数组织分析流程
接下来最重要的一步,是用不同的数据集多加练习。等你能够熟练地用 pandas 加载、浏览、清洗和分析数据之后,就可以着手构建更复杂的数据分析项目了。
祝你编码愉快!