3、Python基础回顾:NumPy数组操作与广播机制,Matplotlib数据可视化,Pandas数据处理基础
说实话,很多初学者一上来就扎进深度学习框架,结果连数据怎么装、怎么画、怎么清洗都搞不定。我见过太多人卡在数据预处理这一步了。今天咱们就把这三个库彻底捋一遍,这些都是我每天写代码都要用的东西。
3.1 NumPy:深度学习的数据骨架
NumPy 的 ndarray 是深度学习中最基础的数据结构。说白了,你训练模型时喂进去的数据,本质上都是 NumPy 数组。PyTorch 和 TensorFlow 的张量,底层设计思路也大量借鉴了 NumPy。
3.1.1 创建数组的几种姿势
我个人习惯用 np.array() 从列表创建,但更常用的是下面这些快捷方式:
import numpy as np
# 全零数组,常用于初始化权重
zeros = np.zeros((3, 4))
# 全一数组
ones = np.ones((2, 3))
# 单位矩阵
eye = np.eye(5)
# 随机数组,这个在初始化参数时特别常用
random_arr = np.random.randn(3, 3) # 标准正态分布
# 等差数列,常用于生成坐标轴
x = np.linspace(0, 10, 100) # 从0到10均匀取100个点
np.random.seed(42) 固定随机种子。这样每次运行结果都一样,调试起来方便很多。
3.1.2 数组形状操作
深度学习里最常干的事就是 reshape。你想想看,一张图片读进来可能是 (H, W, C),但模型输入要求 (batch, C, H, W),这时候就得靠 reshape 和 transpose 了。
arr = np.arange(12) # [0, 1, 2, ..., 11]
# 重塑形状
reshaped = arr.reshape(3, 4) # 变成3行4列
# 展平,这个在连接全连接层时必用
flattened = arr.flatten()
# 转置,图像通道变换时常用
transposed = reshaped.T
# 增加或减少维度
expanded = np.expand_dims(arr, axis=0) # 变成 (1, 12)
squeezed = np.squeeze(expanded) # 去掉维度为1的轴
3.1.3 广播机制:NumPy 的灵魂
广播机制是 NumPy 最强大的特性之一。它允许不同形状的数组进行算术运算。嗯,这里要注意,广播不是万能的,它有严格的规则。
广播的核心规则: 从尾部维度开始比较,要么维度相等,要么其中一个维度为1,要么其中一个数组没有这个维度。
# 经典例子:给每行加上一个偏置
data = np.array([[1, 2, 3],
[4, 5, 6],
[7, 8, 9]])
bias = np.array([10, 20, 30])
# 广播自动将 bias 扩展成 (3, 3)
result = data + bias
print(result)
# [[11 22 33]
# [14 25 36]
# [17 28 39]]
我在项目中遇到过一个问题:两个数组形状分别是 (3, 1) 和 (1, 4),广播后得到 (3, 4)。当时我以为是 bug,后来才发现这就是广播的典型用法,用来做外积运算。
- 给所有样本减去均值(标准化)
- 给每行加上不同的偏置
- 特征缩放时除以标准差
3.2 Matplotlib:让数据说话
做深度学习,可视化是必不可少的。你总得看看损失曲线下降得漂不漂亮,特征分布长什么样吧?Matplotlib 就是干这个的。
3.2.1 快速画图三板斧
import matplotlib.pyplot as plt
# 1. 折线图 - 看损失曲线
epochs = range(1, 101)
loss = [0.9 / (1 + 0.05 * i) for i in epochs] # 模拟损失下降
plt.plot(epochs, loss, label='Training Loss')
plt.xlabel('Epoch')
plt.ylabel('Loss')
plt.title('Loss Curve')
plt.legend()
plt.show()
# 2. 散点图 - 看数据分布
x = np.random.randn(100)
y = 2 * x + 1 + np.random.randn(100) * 0.5
plt.scatter(x, y, alpha=0.6)
plt.xlabel('Feature X')
plt.ylabel('Target Y')
plt.show()
# 3. 直方图 - 看数值分布
data = np.random.randn(1000)
plt.hist(data, bins=30, alpha=0.7, edgecolor='black')
plt.xlabel('Value')
plt.ylabel('Frequency')
plt.show()
3.2.2 子图布局
实际项目中,经常需要把多个图放在一起对比。比如同时看训练损失和验证损失。
fig, axes = plt.subplots(1, 2, figsize=(12, 4))
# 左图:损失曲线
axes[0].plot(epochs, train_loss, label='Train', color='blue')
axes[0].plot(epochs, val_loss, label='Validation', color='red')
axes[0].set_title('Loss')
axes[0].legend()
# 右图:准确率曲线
axes[1].plot(epochs, train_acc, label='Train', color='blue')
axes[1].plot(epochs, val_acc, label='Validation', color='red')
axes[1].set_title('Accuracy')
axes[1].legend()
plt.tight_layout()
plt.show()
3.3 Pandas:数据清洗的瑞士军刀
真实世界的数据哪有那么干净?缺失值、重复值、异常值,什么妖魔鬼怪都有。Pandas 就是用来处理这些脏数据的。
3.3.1 读取与预览数据
import pandas as pd
# 读取 CSV 文件
df = pd.read_csv('data.csv')
# 快速预览
print(df.head()) # 前5行
print(df.info()) # 数据类型和缺失值
print(df.describe()) # 统计摘要
# 查看列名
print(df.columns.tolist())
3.3.2 数据清洗三板斧
第一板斧:处理缺失值
# 检查缺失值
print(df.isnull().sum())
# 删除有缺失值的行
df_clean = df.dropna()
# 填充缺失值(常用方法)
df['age'].fillna(df['age'].median(), inplace=True) # 用中位数填充
df['income'].fillna(0, inplace=True) # 用0填充
df['category'].fillna('Unknown', inplace=True) # 用固定值填充
第二板斧:处理重复值
# 检查重复行
print(df.duplicated().sum())
# 删除重复行
df_unique = df.drop_duplicates()
# 按指定列去重
df_unique = df.drop_duplicates(subset=['user_id'])
第三板斧:处理异常值
# 用 IQR 方法检测异常值
Q1 = df['price'].quantile(0.25)
Q3 = df['price'].quantile(0.75)
IQR = Q3 - Q1
lower_bound = Q1 - 1.5 * IQR
upper_bound = Q3 + 1.5 * IQR
# 过滤异常值
df_filtered = df[(df['price'] >= lower_bound) & (df['price'] <= upper_bound)]
3.3.3 数据变换与分组
# 创建新特征
df['age_group'] = pd.cut(df['age'], bins=[0, 18, 35, 60, 100],
labels=['少年', '青年', '中年', '老年'])
# 分组聚合
grouped = df.groupby('age_group')['income'].agg(['mean', 'std', 'count'])
print(grouped)
# 数据透视表
pivot = pd.pivot_table(df, values='income', index='age_group',
columns='gender', aggfunc='mean')
3.4 三个库的协同工作
实际项目中,这三个库是配合使用的。我一般的工作流是这样的:
- Pandas 读取和清洗数据:处理缺失值、异常值、特征工程
- NumPy 转换数据格式:把 DataFrame 转成 ndarray,做标准化、归一化
- Matplotlib 可视化验证:画分布图、相关性热力图,确认数据质量
# 完整示例:数据预处理流水线
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
# 1. 读取数据
df = pd.read_csv('housing.csv')
# 2. 清洗:填充缺失值
df['total_bedrooms'].fillna(df['total_bedrooms'].median(), inplace=True)
# 3. 特征工程:创建新特征
df['rooms_per_household'] = df['total_rooms'] / df['households']
# 4. 转换为 NumPy 数组
features = ['median_income', 'rooms_per_household', 'housing_median_age']
X = df[features].values
# 5. 标准化
mean = X.mean(axis=0)
std = X.std(axis=0)
X_normalized = (X - mean) / std
# 6. 可视化验证
plt.figure(figsize=(10, 6))
plt.hist(X_normalized[:, 0], bins=50, alpha=0.7)
plt.title('Normalized Median Income Distribution')
plt.show()
- NumPy 负责数学运算和数组操作,广播机制要烂熟于心
- Matplotlib 负责可视化,损失曲线和分布图是调试利器
- Pandas 负责数据清洗,缺失值和异常值处理是基本功
这三个库是深度学习的基石。我建议你花一周时间,把上面的代码都敲一遍。相信我,后面学 PyTorch 的时候,你会感谢现在的自己。
公众号:蓝海资料掘金营,微信deep3321