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
相关推荐
东坡肘子6 分钟前
SPI 加入 Apple,Swift 迈向自举 -- 肘子的 Swift 周报 #142
人工智能·swiftui·swift
小和尚同志8 小时前
AI 自动化测试探索(二):Chrome-devtools MCP
人工智能·e2e·aigc
花酒锄作田9 小时前
Pydantic校验配置文件
python
hboot9 小时前
AI工程师第四课 - 深度学习入门
pytorch·python·神经网络
冬奇Lab10 小时前
Workflow 系列(02):设计范式——四层架构、三种 Context 传递模式与确认门设计
人工智能·agent·工作流引擎
冬奇Lab11 小时前
每日一个开源项目(第145篇):Trellis - 把项目记忆、规范和任务上下文持久化进代码仓库
人工智能·开源·资讯
有道AI情报局11 小时前
Harness即产品
人工智能·agent
罗西的思考12 小时前
机器人 / 强化学习】HIL-SERL:人类在环驱动的具身智能进化框架
人工智能·算法·机器学习
IT_陈寒13 小时前
SpringBoot自动配置的坑,我的API突然就404了
前端·人工智能·后端
笃行35013 小时前
从零到上线:用 EdgeOne Makers + CodeBuddy 搭一个「对账核对员」AI Agent
人工智能