【机器学习基础【5】】Python数据科学三件套:从数据创建到处理再到可视化实战
文章目录
- 一、三个工具库介绍
- 二、环境准备
- 第一部分:用NumPy创建和处理数据
- 1、NumPy的核心
- 2、实战演练:模拟数据及数据操作
- 第二部分:用Pandas进行数据处理
- 1、Pandas的DataFrame
- 2、构建学生数据表:numpy转dataframe
- 3、核心的数据操作
- 第三部分:用Matplotlib实现数据可视化
- 1、实战演练:创建综合分析图表
- 2、实践要点:让图表更有说服力
- 四、综合实战项目:完整的数据分析流程
- 五、要点总结
本文通过一个完整的数据分析项目,让您在实践中掌握NumPy、Pandas、Matplotlib三大工具库的核心用法。我们将从原始数据创建开始,经过数据处理,最终实现数据可视化。
项目代码见:【机器学习】numpy-pandas-matplotlib 基础实战
一、三个工具库介绍
在数据科学领域,有一个经典的工作流程:数据准备 → 数据处理 → 数据可视化。这三个工具库正好对应这个流程的核心环节:
- NumPy:提供高效的数值计算基础,是其他工具库的底层支撑
- Pandas:专门用于数据清洗、转换和分析,是数据处理的利器
- Matplotlib:实现数据可视化,让数据"说话"
二、环境准备
基于pycharm 进行开发,先设置interpreter,基于conda虚拟环境,然后写一个requirements.txt文件。
可参考:【Python虚拟环境【一】】PyCharm虚拟环境配置:不同虚拟环境的配置策略
requirements.txt
numpy
scipy
pandas
matplotlib
scikit-learn
引入依赖
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
第一部分:用NumPy创建和处理数据
1、NumPy的核心
NumPy的核心是ndarray(多维数组),它比Python原生列表快10-100倍。原因在于:
- 内存连续存储:元素在内存中紧密排列,提高缓存效率
- 矢量化运算:底层用C语言实现,避免Python循环的开销
- 统一数据类型:所有元素类型相同,减少类型检查
2、实战演练:模拟数据及数据操作
# 一、创建模拟数据:100名学生的数学、英语、物理成绩
np.random.seed(42) # 确保结果可重现# 生成正态分布的成绩数据
math_scores = np.random.normal(75, 12, 100) # 均值75,标准差12
english_scores = np.random.normal(80, 10, 100) # 均值80,标准差10
physics_scores = np.random.normal(70, 15, 100) # 均值70,标准差15# 合并成二维数组:每行代表一个学生,每列代表一门科目
scores = np.column_stack([math_scores, english_scores, physics_scores])print(f"数据形状:{scores.shape}") # (100, 3)
print(f"数据类型:{scores.dtype}") # float64# 二、简单数据操作
# 1. 条件筛选:找出数学成绩大于80的学生
high_math = scores[scores[:, 0] > 80]
print(f"数学成绩优秀的学生数量:{len(high_math)}")# 2. 矢量运算:计算每个学生的总分
total_scores = np.sum(scores, axis=1)
print(f"平均总分:{np.mean(total_scores):.2f}")# 3. 数组重塑:将数据转换为便于分析的形式
# 将100x3的成绩矩阵重塑为300x1的向量(用于后续统计)
all_scores_flat = scores.flatten()输出如下:
数据形状:(100, 3)
数据类型:float64
数学成绩优秀的学生数量:25
平均总分:224.95
关键理解:NumPy的强大之处在于能够用简洁的代码处理大量数据,这为后续的数据处理奠定了基础。
第二部分:用Pandas进行数据处理
1、Pandas的DataFrame
Pandas的DataFrame建立在NumPy之上,但提供了更丰富的功能:
- 带标签的数据结构:行和列都有名称,更符合人类思维
- 异构数据支持:不同列可以有不同的数据类型
- 强大的数据操作:分组、合并、透视等高级功能
2、构建学生数据表:numpy转dataframe
# 将NumPy数组转换为DataFrame
student_data = pd.DataFrame({'student_id': range(1, 101),'math': scores[:, 0],'english': scores[:, 1],'physics': scores[:, 2]
})# 添加衍生信息
student_data['total_score'] = student_data[['math', 'english', 'physics']].sum(axis=1)
student_data['average_score'] = student_data['total_score'] / 3# 添加等级分类
def get_grade(avg_score):if avg_score >= 90:return 'A'elif avg_score >= 80:return 'B'elif avg_score >= 70:return 'C'else:return 'D'student_data['grade'] = student_data['average_score'].apply(get_grade)print(student_data.head())
输入如下:
3、核心的数据操作
# 1. 数据概览:快速了解数据分布
print("数据基本统计:")
print(student_data[['math', 'english', 'physics']].describe())# 2. 分组分析:按等级分组查看人数分布
grade_distribution = student_data['grade'].value_counts()
print("\n等级分布:")
print(grade_distribution)# 3. 条件筛选:找出需要重点关注的学生
struggling_students = student_data[student_data['average_score'] < 60]
print(f"\n需要关注的学生数量:{len(struggling_students)}")# 4. 数据透视:分析科目间的关系
subject_correlation = student_data[['math', 'english', 'physics']].corr()
print("\n科目间相关性:")
print(subject_correlation)
关键理解:Pandas让我们能够像处理Excel表格一样处理数据,但具有更强大的编程能力和更高的效率。
第三部分:用Matplotlib实现数据可视化
1、实战演练:创建综合分析图表
# 使用英文标签避免字体问题
fig, axes = plt.subplots(2, 2, figsize=(12, 10))
fig.suptitle('Student Performance Analysis', fontsize=16, fontweight='bold')# 1. 成绩分布直方图
axes[0, 0].hist(student_data['average_score'], bins=20, alpha=0.7, color='skyblue')
axes[0, 0].set_title('Average Score Distribution')
axes[0, 0].set_xlabel('Average Score')
axes[0, 0].set_ylabel('Number of Students')# 2. 科目成绩对比箱线图
subject_data = [student_data['math'], student_data['english'], student_data['physics']]
axes[0, 1].boxplot(subject_data, tick_labels=['Math', 'English', 'Physics'])
axes[0, 1].set_title('Subject Score Distribution')
axes[0, 1].set_ylabel('Score')# 3. 等级分布饼图
axes[1, 0].pie(grade_distribution.values, labels=grade_distribution.index,autopct='%1.1f%%', startangle=90)
axes[1, 0].set_title('Grade Distribution')# 4. 科目间相关性散点图
axes[1, 1].scatter(student_data['math'], student_data['english'], alpha=0.6)
axes[1, 1].set_xlabel('Math Score')
axes[1, 1].set_ylabel('English Score')
axes[1, 1].set_title('Math vs English Score Correlation')plt.tight_layout()
plt.show()
2、实践要点:让图表更有说服力
# 创建一个更深入的分析图表
fig, ax = plt.subplots(figsize=(10, 6))# 按等级分组,展示不同等级学生的科目表现
grades = ['A', 'B', 'C', 'D']
subjects = ['math', 'english', 'physics']# 计算各等级在各科目的平均分
grade_subject_avg = student_data.groupby('grade')[subjects].mean()# 创建分组柱状图
x = np.arange(len(subjects))
width = 0.2for i, grade in enumerate(grades):if grade in grade_subject_avg.index:values = grade_subject_avg.loc[grade]ax.bar(x + i * width, values, width, label=f'等级{grade}', alpha=0.8)ax.set_xlabel('科目')
ax.set_ylabel('平均分')
ax.set_title('不同等级学生的科目表现对比')
ax.set_xticks(x + width * 1.5)
ax.set_xticklabels(subjects)
ax.legend()
ax.grid(axis='y', alpha=0.3)plt.tight_layout()
plt.show()
关键理解:好的可视化不仅要美观,更要能够清晰地传达数据背后的洞察。
四、综合实战项目:完整的数据分析流程
让我们将三个工具库结合起来,完成一个完整的数据分析项目:
# 项目目标:分析学生成绩数据,提出教学建议# 步骤1:数据准备(NumPy)
np.random.seed(42)
n_students = 200# 模拟更复杂的数据:考虑学生的学习时间影响
study_hours = np.random.exponential(2, n_students) + 1 # 学习时间(小时/天)
base_ability = np.random.normal(0, 1, n_students) # 基础能力# 成绩与学习时间和基础能力相关
math_scores = 60 + 15 * base_ability + 5 * study_hours + np.random.normal(0, 8, n_students)
english_scores = 65 + 12 * base_ability + 4 * study_hours + np.random.normal(0, 7, n_students)
physics_scores = 55 + 18 * base_ability + 6 * study_hours + np.random.normal(0, 10, n_students)# 确保成绩在合理范围内
math_scores = np.clip(math_scores, 0, 100)
english_scores = np.clip(english_scores, 0, 100)
physics_scores = np.clip(physics_scores, 0, 100)# 步骤2:数据处理(Pandas)
df = pd.DataFrame({'student_id': range(1, n_students + 1),'study_hours': study_hours,'math': math_scores,'english': english_scores,'physics': physics_scores
})# 数据分析
df['total_score'] = df[['math', 'english', 'physics']].sum(axis=1)
df['average_score'] = df['total_score'] / 3# 学习效率分析
df['efficiency'] = df['average_score'] / df['study_hours']# 步骤3:可视化分析(Matplotlib)
fig, axes = plt.subplots(2, 2, figsize=(14, 10))
fig.suptitle('学生学习效果综合分析报告', fontsize=16, fontweight='bold')# 分析1:学习时间与成绩的关系
axes[0, 0].scatter(df['study_hours'], df['average_score'], alpha=0.6, color='blue')
axes[0, 0].set_xlabel('每日学习时间(小时)')
axes[0, 0].set_ylabel('平均成绩')
axes[0, 0].set_title('学习时间与成绩关系')# 添加趋势线
z = np.polyfit(df['study_hours'], df['average_score'], 1)
p = np.poly1d(z)
axes[0, 0].plot(df['study_hours'], p(df['study_hours']), "r--", alpha=0.8)# 分析2:学习效率分布
axes[0, 1].hist(df['efficiency'], bins=30, alpha=0.7, color='green')
axes[0, 1].set_xlabel('学习效率(分数/小时)')
axes[0, 1].set_ylabel('学生数量')
axes[0, 1].set_title('学习效率分布')# 分析3:不同学习时间段的成绩对比
df['study_category'] = pd.cut(df['study_hours'], bins=[0, 2, 4, 6, float('inf')], labels=['<2h', '2-4h', '4-6h', '>6h'])study_group_avg = df.groupby('study_category')['average_score'].mean()
axes[1, 0].bar(study_group_avg.index, study_group_avg.values, alpha=0.7, color='orange')
axes[1, 0].set_xlabel('学习时间段')
axes[1, 0].set_ylabel('平均成绩')
axes[1, 0].set_title('不同学习时间段的成绩表现')# 分析4:科目间成绩相关性热力图
import matplotlib.colors as mcolorscorr_matrix = df[['math', 'english', 'physics']].corr()
im = axes[1, 1].imshow(corr_matrix, cmap='coolwarm', aspect='auto')
axes[1, 1].set_xticks(range(len(corr_matrix.columns)))
axes[1, 1].set_yticks(range(len(corr_matrix.columns)))
axes[1, 1].set_xticklabels(corr_matrix.columns)
axes[1, 1].set_yticklabels(corr_matrix.columns)
axes[1, 1].set_title('科目间相关性')# 添加数值标签
for i in range(len(corr_matrix.columns)):for j in range(len(corr_matrix.columns)):text = axes[1, 1].text(j, i, f'{corr_matrix.iloc[i, j]:.2f}',ha="center", va="center", color="black")plt.tight_layout()
plt.show()# 输出关键洞察
print("=== 数据分析结果 ===")
print(f"1. 学习时间与成绩的相关系数: {df['study_hours'].corr(df['average_score']):.3f}")
print(f"2. 平均学习效率: {df['efficiency'].mean():.2f} 分/小时")
print(f"3. 最高效率学生ID: {df.loc[df['efficiency'].idxmax(), 'student_id']}")
print(f"4. 各科目平均分: 数学{df['math'].mean():.1f}, 英语{df['english'].mean():.1f}, 物理{df['physics'].mean():.1f}")
=== Data Analysis Results ===
- Correlation between study time and performance: 0.519
- Average learning efficiency: 33.95 points/hour
- Most efficient student ID: 172
- Average scores by subject: Math 74.2, English 76.6, Physics 73.8
五、要点总结
通过这个完整的实战项目,我们掌握了三个工具库的核心用法:
进阶学习建议
- NumPy进阶:学习线性代数运算、傅里叶变换等科学计算功能
- Pandas深入:掌握时间序列分析、数据透视表、数据库连接
- Matplotlib扩展:探索Seaborn、Plotly等高级可视化库