PyTorch 基础:数据操作与数据预处理

数据操作与数据预处理

本文整理自李沐老师《动手学深度学习》课程笔记,涵盖张量的基本操作与 Pandas 数据预处理流程,是深度学习入门的必备基础。


一、数据操作:张量基础

1. 创建张量

python 复制代码
import torch

x = torch.arange(12)        # 创建 0~11 的一维张量
x.shape                     # 查看形状:torch.Size([12])
x.numel()                   # 查看标量总个数:12

x = x.reshape(3, 4)         # 变形为 3×4 矩阵
                            # reshape 返回的是 view(视图),与原张量共享内存

torch.zeros((2, 3, 4))      # 全零张量
torch.ones((2, 3, 4))       # 全一张量
torch.tensor([[1, 2], [3, 4]])  # 由 Python 列表创建张量

2. 基本运算

python 复制代码
x = torch.tensor([1.0, 2, 4, 8])
y = torch.tensor([2, 2, 2, 2])

x + y   # 加
x - y   # 减
x * y   # 乘
x / y   # 除
x ** y  # 幂运算(** 是求幂运算符)

3. 张量拼接

python 复制代码
x = torch.arange(12, dtype=torch.float32).reshape(3, 4)
y = torch.tensor([[1, 2, 3, 4],
                  [1, 2, 3, 4],
                  [1, 2, 3, 4]])

torch.cat((x, y), dim=0)  # 沿行方向拼接,结果形状 (6, 4)
torch.cat((x, y), dim=1)  # 沿列方向拼接,结果形状 (3, 8)

4. 逻辑判断与求和

python 复制代码
x == y    # 逐元素比较,返回布尔张量
x.sum()   # 对所有元素求和,返回标量张量

5. 广播机制

不同形状的张量相加时,PyTorch 会自动触发广播(Broadcasting):

python 复制代码
x = torch.arange(3).reshape(3, 1)  # 形状 (3, 1)
y = torch.arange(2).reshape(1, 2)  # 形状 (1, 2)

x + y  # 广播后结果形状为 (3, 2)

6. 索引与切片

python 复制代码
x[-1]     # 最后一行
x[1:3]    # 第 1~2 行(左闭右开)
x[1, 0] = 9  # 修改指定位置的值

7. 内存管理:原地操作

python 复制代码
before = id(y)
y = y + x          # 为新结果分配了新内存
id(y) == before    # False,y 指向了新地址

# 原地操作:避免重复分配内存
z = torch.zeros_like(y)
print(id(z))
z[:] = x + y       # 原地写入,z 的地址不变
print(id(z))       # 与上面相同

为什么要在意内存?

在大规模模型训练中,反复执行 x = x + y 会不断申请新内存,极易导致内存溢出。

使用 x[:] = x + yx += y 可以做到原地更新,显著降低内存开销。

8. 与 NumPy 互转

python 复制代码
a = x.numpy()           # Tensor → NumPy ndarray
b = torch.tensor(a)     # NumPy ndarray → Tensor
type(a), type(b)

9. 单元素张量转 Python 标量

python 复制代码
a = torch.tensor([3.5])
a.item()   # 转为 Python float
float(a)   # 同上
int(a)     # 转为 Python int

二、数据预处理:从 CSV 到张量

真实场景中,数据往往以表格形式存储,需要经过读取、清洗、编码等步骤后才能喂给模型。

1. 创建示例数据集

python 复制代码
import os
import pandas as pd
import torch

os.makedirs(os.path.join('.', 'data'), exist_ok=True)
data_file = os.path.join('.', 'data', 'house_tiny.csv')

with open(data_file, 'w') as f:
    f.write('NumRooms,Alley,Price\n')
    f.write('NA,Pave,127500\n')
    f.write('2,NA,106000\n')
    f.write('4,NA,178100\n')
    f.write('NA,NA,140000\n')

2. 读取与分割数据

python 复制代码
data = pd.read_csv(data_file)
print(data)

inputs, outputs = data.iloc[:, 0:2], data.iloc[:, 2]

3. 缺失值处理

python 复制代码
# 注意:直接 fillna(mean()) 会因非数值列报错
# 正确做法:只对数值列做均值填充

numeric_cols = inputs.select_dtypes(include='number').columns
inputs[numeric_cols] = inputs[numeric_cols].fillna(inputs[numeric_cols].mean())
print(inputs)

4. 类别特征独热编码

python 复制代码
# get_dummies 将字符串列转为 0/1 编码,dummy_na=True 会为 NaN 单独生成一列
inputs = pd.get_dummies(inputs, dummy_na=True, dtype=int)
print(inputs)

5. 转换为张量

python 复制代码
X = torch.tensor(inputs.values)
y = torch.tensor(outputs.values)
# 注意:Pandas 默认转为 float64,但深度学习中通常使用 float32
# 如有需要,可指定:torch.tensor(inputs.values, dtype=torch.float32)
X, y

三、小结

知识点 核心要点
reshape 返回 view,与原张量共享内存
广播机制 形状不同的张量运算时自动扩展维度
原地操作 x += y / x[:] = ... 避免内存浪费
缺失值处理 数值列均值填充,类别列独热编码
张量类型 深度学习中优先使用 float32
相关推荐
水如烟2 小时前
孤能子视角:EIS看宇宙创生寂灭假说——人类宇宙学假说的操作描述重显影
人工智能
Elastic 中国社区官方博客2 小时前
从建议到修复的 4 个阶段:使用 Elastic Workflows 实现人在回路中的自动化
运维·数据库·人工智能·后端·elasticsearch·ai·自动化
码视野2 小时前
基于 Spring Boot + Vue3 的【城市地下燃气管网微泄漏感知与相邻地下空间燃爆预警中台】设计与实现(含PRD/三端高保真源码/大屏)
java·前端·人工智能·spring boot·后端
土星云SaturnCloud2 小时前
大型仓储AI视觉全场景落地实战:安全·效率·库存,32TOPS土星云边缘算力赋能分区部署
服务器·人工智能·ai·边缘计算
智塑未来2 小时前
2026年边缘计算网关哪个品牌好?多厂商边缘算力能力横评
人工智能·边缘计算
梯度下降者2 小时前
CukeTest 自动化测试工具2023年度回顾白皮书
自动化测试·python·cuketest·qtquick/qml·linuxatk
ShallWeL3 小时前
【Agent工程】(6)—— 危险写操作与二次确认
人工智能·agent·工作流·智能体
具身AGI3 小时前
基座模型架构之争,物理AI 人类学习路线 的双脑答案
人工智能·学习·架构
DeepIntelli3 小时前
GEO服务、传统网页优化与AI问答引流的区别:从工程视角看三者的目标、链路与验收方式
人工智能
SmartBrain3 小时前
以史为鉴,对AI时代企业数字化转型的启示
人工智能·架构·创业创新