目录
1. 引言
数据分析是现代商业决策和科学研究的重要基础,而 Pandas 是 Python 中最流行的数据分析库之一。Pandas 提供了高效、灵活的数据结构,使得数据操作更加简单且直观。本文将通过一个实际项目示例来介绍使用 Pandas 进行数据分析的常见步骤,帮助大家深入理解其应用。
2. 项目背景与数据介绍
假设我们正在分析某学校的学生成绩数据,目标是通过分析了解学生的整体表现、识别学科薄弱环节、并为后续的教学调整提供数据支持。
我们假设有一个 CSV 文件 student_scores.csv
,包含以下数据:
StudentID | Name | Math | English | Science | History |
---|---|---|---|---|---|
1 | Alice | 85 | 78 | 92 | 88 |
2 | Bob | 70 | 80 | 75 | 85 |
3 | Charlie | 90 | 88 | 95 | 90 |
4 | David | NaN | 70 | 80 | 75 |
5 | Eva | 60 | 65 | 70 | NaN |
每一列代表一个学生的不同科目的成绩,其中 NaN
表示缺失值。
3. 安装与导入 Pandas
首先,确保你已经安装了 Pandas 库。如果尚未安装,可以使用以下命令:
pip install pandas
在你的 Python 脚本中,导入 Pandas:
import pandas as pd
在这里,pd
是我们给 Pandas 库起的别名,方便后续调用。
4. 数据读取
使用 pd.read_csv()
方法读取数据:
df = pd.read_csv('student_scores.csv')
print(df.head()) # 输出数据的前五行
pd.read_csv()
是 Pandas 用于读取 CSV 文件的函数。它会将 CSV 文件内容转化为 Pandas 的 DataFrame 结构。head()
方法用于查看 DataFrame 的前几行数据,默认返回前五行。这样可以快速了解数据的基本情况。
5. 数据探索
数据探索的目的是了解数据的结构和基本特性,以便为后续处理做好准备。
5.1 查看数据结构
使用 info()
方法查看数据的基本信息:
print(df.info())
info()
方法提供了数据框的整体结构,包括每一列的名称、数据类型、非空值计数等。这样可以帮助我们快速了解数据的特征和潜在问题。
5.2 描述性统计
使用 describe()
方法获取数值型数据的统计信息:
print(df.describe())
describe()
方法返回数值列的基本统计量,包括计数、均值、标准差、最小值、25%分位数、50%分位数(中位数)、75%分位数和最大值。这对于理解数据的分布特性非常重要。
5.3 处理缺失值
查找缺失值的数量:
print(df.isnull().sum())
isnull()
方法返回一个与原数据结构相同的布尔型 DataFrame,标识每个值是否为缺失值(NaN
)。sum()
方法则计算每一列中缺失值的总数。
处理缺失值,我们可以选择填充或删除:
# 用均值填充 Math 分数的缺失值
df['Math'].fillna(df['Math'].mean(), inplace=True)
# 用均值填充 History 分数的缺失值
df['History'].fillna(df['History'].mean(), inplace=True)
fillna()
方法用于填充缺失值,inplace=True
参数表示直接在原 DataFrame 上修改。这里我们用每列的均值来填充缺失值,这是一种常见的处理方式。
6. 数据清洗
数据清洗是数据分析中非常重要的一步,旨在确保数据的质量和一致性。
6.1 重命名列
为了更好地分析,我们可以重命名列,以便更符合我们的分析目的:
df.rename(columns={'StudentID': 'ID', 'Name': 'Student Name'}, inplace=True)
rename()
方法用于重命名列,columns
参数接受一个字典,字典的键是旧列名,值是新列名。
6.2 删除重复值
检查并删除任何重复行:
df.drop_duplicates(inplace=True)
drop_duplicates()
方法用于删除重复的行,inplace=True
表示在原 DataFrame 上修改。保持数据的唯一性对分析质量至关重要。
6.3 数据类型转换
确保所有分数列都是数值型,这对后续的统计分析非常重要:
df['Math'] = pd.to_numeric(df['Math'], errors='coerce')
df['English'] = pd.to_numeric(df['English'], errors='coerce')
df['Science'] = pd.to_numeric(df['Science'], errors='coerce')
df['History'] = pd.to_numeric(df['History'], errors='coerce')
pd.to_numeric()
方法用于将列转换为数值类型,errors='coerce'
表示如果转换失败(例如字符型的内容),将其设置为NaN
。
7. 数据操作
数据操作包括数据的筛选、排序和聚合等,旨在提取有用的信息。
7.1 数据过滤
筛选出分数高于 75 的学生:
high_scorers = df[df['Math'] > 75]
print(high_scorers)
- 通过布尔索引,可以根据条件选择特定的行。在此示例中,
df['Math'] > 75
创建了一个布尔型的 Series,表示每个学生的数学成绩是否大于 75。
7.2 数据排序
按照 Math 分数对数据进行排序:
sorted_df = df.sort_values(by='Math', ascending=False)
print(sorted_df)
sort_values()
方法用于对 DataFrame 进行排序,by
参数指定排序的列,ascending=False
表示降序排序。
7.3 数据分组与聚合
计算每门科目的平均分:
mean_scores = df[['Math', 'English', 'Science', 'History']].mean()
print(mean_scores)
- 使用
mean()
方法可以计算 DataFrame 中每列的均值。这里,我们选择了四个科目的列,通过[['Math', 'English', 'Science', 'History']]
来指定。
8. 数据可视化
数据可视化是分析过程中不可或缺的一部分,可以帮助我们更直观地理解数据。
8.1 使用 Matplotlib 进行可视化
首先,确保安装了 Matplotlib:
pip install matplotlib
绘制每门科目的分数分布直方图:
import matplotlib.pyplot as plt
df[['Math', 'English', 'Science', 'History']].hist(bins=10, figsize=(10, 6))
plt.suptitle('Score Distribution')
plt.show()
hist()
方法用于绘制直方图,bins
表示分组的数量,figsize
设置图形的大小。suptitle()
方法用于添加整体标题。
8.2 使用 Seaborn 进行可视化
首先,确保安装了 Seaborn:
pip install seaborn
绘制各科目的箱型图,比较不同学科的分数分布:
import seaborn as sns
sns.boxplot(data=df[['Math', 'English', 'Science', 'History']])
plt.title('Score Boxplot')
plt.show()
boxplot()
方法用于绘制箱型图,能够直观地展示数据的分布情况,包括中位数、四分位数和异常值。
9. 完整示例
9.1 代码
# 导入必要的库
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
# 1. 读取数据
# 使用 Pandas 读取 CSV 文件
df = pd.read_csv('student_scores.csv')
print("初始数据:")
print(df.head()) # 输出数据的前五行以查看结构
# 2. 数据探索
print("\n数据结构信息:")
print(df.info()) # 查看数据的整体结构
print("\n描述性统计:")
print(df.describe()) # 查看数值型数据的描述性统计
print("\n缺失值统计:")
print(df.isnull().sum()) # 查看每列的缺失值数量
# 3. 处理缺失值
# 用均值填充 Math 和 History 分数的缺失值
df['Math'].fillna(df['Math'].mean(), inplace=True)
df['History'].fillna(df['History'].mean(), inplace=True)
# 4. 数据清洗
# 重命名列
df.rename(columns={'StudentID': 'ID', 'Name': 'Student Name'}, inplace=True)
# 删除重复值
df.drop_duplicates(inplace=True)
# 确保所有分数列都是数值型
df['Math'] = pd.to_numeric(df['Math'], errors='coerce')
df['English'] = pd.to_numeric(df['English'], errors='coerce')
df['Science'] = pd.to_numeric(df['Science'], errors='coerce')
df['History'] = pd.to_numeric(df['History'], errors='coerce')
# 5. 数据操作
# 筛选出 Math 分数高于 75 的学生
high_scorers = df[df['Math'] > 75]
print("\nMath 分数高于 75 的学生:")
print(high_scorers)
# 按照 Math 分数排序
sorted_df = df.sort_values(by='Math', ascending=False)
print("\n按 Math 分数排序的学生:")
print(sorted_df)
# 计算每门科目的平均分
mean_scores = df[['Math', 'English', 'Science', 'History']].mean()
print("\n每门科目的平均分:")
print(mean_scores)
# 6. 数据可视化
# 绘制直方图显示分数分布
df[['Math', 'English', 'Science', 'History']].hist(bins=10, figsize=(10, 6))
plt.suptitle('Score Distribution')
plt.show()
# 绘制箱型图比较各科目的分数分布
sns.boxplot(data=df[['Math', 'English', 'Science', 'History']])
plt.title('Score Boxplot')
plt.show()
9.2 输出展示
初始数据:
StudentID Name Math English Science History
0 1 Alice 85.0 78 92 88.0
1 2 Bob 70.0 80 75 85.0
2 3 Charlie 90.0 88 95 90.0
3 4 David NaN 70 80 75.0
4 5 Eva 60.0 65 70 NaN
数据结构信息:
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 5 entries, 0 to 4
Data columns (total 6 columns):
# Column Non-Null Count Dtype
--- ------ -------------- -----
0 StudentID 5 non-null int64
1 Name 5 non-null object
2 Math 4 non-null float64
3 English 5 non-null int64
4 Science 5 non-null int64
5 History 4 non-null float64
dtypes: float64(2), int64(3), object(1)
memory usage: 368.0+ bytes
None
描述性统计:
StudentID Math English Science History
count 5.000000 4.000000 5.000000 5.000000 4.000000
mean 3.000000 76.250000 76.200000 82.400000 84.500000
std 1.581139 13.768926 8.955445 10.784248 6.658328
min 1.000000 60.000000 65.000000 70.000000 75.000000
25% 2.000000 67.500000 70.000000 75.000000 82.500000
50% 3.000000 77.500000 78.000000 80.000000 86.500000
75% 4.000000 86.250000 80.000000 92.000000 88.500000
max 5.000000 90.000000 88.000000 95.000000 90.000000
缺失值统计:
StudentID 0
Name 0
Math 1
English 0
Science 0
History 1
dtype: int64
Math 分数高于 75 的学生:
ID Student Name Math English Science History
0 1 Alice 85.00 78 92 88.0
2 3 Charlie 90.00 88 95 90.0
3 4 David 76.25 70 80 75.0
按 Math 分数排序的学生:
ID Student Name Math English Science History
2 3 Charlie 90.00 88 95 90.0
0 1 Alice 85.00 78 92 88.0
3 4 David 76.25 70 80 75.0
1 2 Bob 70.00 80 75 85.0
4 5 Eva 60.00 65 70 84.5
每门科目的平均分:
Math 76.25
English 76.20
Science 82.40
History 84.50
dtype: float64