[研0知识学习打卡]python数据预处理
在这段代码中: - `b = a.reshape((3,4))` 对`a`进行形状重塑后,`b`与`a`共享同一块内存;- 当执行`b[:] = 2`修改`b`的所有元素时,由于内存共享,`a`的对应元素也会被同步修改。1.在张量(如PyTorch的`Tensor`或NumPy的`ndarray`)操作中,`reshape`方法在满足条件时(元素总数不变且内存布局兼容),会返回原张量的视图(共享底
目录
一、数据创建与存储模块
-
os.makedirs(path, exist_ok=True)- 作用:创建多级目录,避免手动逐层创建的繁琐;
exist_ok=True保证目录已存在时不报错。 - 使用场景:数据文件存储前的目录预处理。
- 作用:创建多级目录,避免手动逐层创建的繁琐;
-
os.path.join(part1, part2, ...)- 作用:跨平台拼接文件路径(自动适配 Windows 的
\和 Linux/macOS 的/)。 - 使用场景:确保路径在不同操作系统下的兼容性。
- 作用:跨平台拼接文件路径(自动适配 Windows 的
-
open(file, mode) + write()- 作用:以指定模式(如
'w'为写入)打开文件,逐行写入 CSV 格式数据,每行代表一条样本,列以逗号分隔。 - 使用场景:自定义小数据集的创建与存储。
- 作用:以指定模式(如
二、Pandas 数据处理模块
-
pd.read_csv(file)- 作用:读取 CSV 文件并转换为DataFrame(Pandas 核心数据结构,类似表格)。
- 使用场景:加载外部表格数据(如 CSV、TSV)。
-
DataFrame.fillna(value)- 作用:填充数据中的缺失值(
NaN),此处用inputs.mean()对数值列(如NumRooms)填充均值,保留数据统计特征。 - 使用场景:缺失值预处理,避免因缺失值导致模型训练报错。
- 作用:填充数据中的缺失值(
-
pd.get_dummies(df, dummy_na, dtype)- 作用:将类别型特征(如
Alley)转换为One-Hot 编码(虚拟变量),使离散类别能被数值型模型识别。 - 参数:
dummy_na=True将NaN视为独立类别;dtype=float(新增)确保输出为浮点型,兼容后续 PyTorch 张量的类型要求。 - 使用场景:类别特征向量化,为模型输入做准备。
- 作用:将类别型特征(如
三、PyTorch 张量转换模块
torch.tensor(data)- 作用:将 Pandas/NumPy 的数值型数据转换为 PyTorch 张量(深度学习的核心数据结构)。
- 使用场景:将预处理后的数据输入神经网络模型。
四、代码示例:
import os
import pandas as pd
import torch
# ===================== 步骤1:创建并写入CSV数据文件 =====================
# 创建上级目录下的data文件夹(exist_ok=True避免目录已存在时报错)
os.makedirs(os.path.join('..', 'data'), exist_ok=True)
# 拼接CSV文件的完整路径
data_file = os.path.join('..', 'data', 'house_tiny.csv')
# 以写入模式打开文件,with上下文管理器会自动关闭文件
with open(data_file, 'w') as f:
# 写入列名:房间数、巷子类型、房价
f.write('NumRooms,Alley,Price\n')
# 写入4条样本数据,NA表示缺失值
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:Pandas读取与数据清洗 =====================
# 读取CSV文件为DataFrame
data = pd.read_csv(data_file)
print("原始数据(含缺失值):\n", data)
# 分离输入特征(前2列)和输出标签(第3列)
inputs, outputs = data.iloc[:, 0:2], data.iloc[:, 2]
# 缺失值填充:数值列(NumRooms)用列均值填充
inputs = inputs.fillna(inputs.mean())
print("\n缺失值填充后(数值列用均值填充):\n", inputs)
# 类别特征One-Hot编码:将Alley的类别(含NaN)转换为虚拟变量
# dummy_na=True:把NaN视为一个独立类别;dtype=float:输出为浮点型,兼容PyTorch
inputs = pd.get_dummies(inputs, dummy_na=True, dtype=float)
print("\nOne-Hot编码后的输入特征:\n", inputs)
# ===================== 步骤3:转换为PyTorch张量 =====================
# 将Pandas数据转换为PyTorch张量(模型可直接使用的格式)
X = torch.tensor(inputs.values) # 输入特征张量
y = torch.tensor(outputs.values) # 输出标签张量
print("\nPyTorch输入特征张量 X:")
print(X)
X
print("PyTorch输出标签张量 y:")
print(y)
y
输出结果:
原始数据(含缺失值):
NumRooms Alley Price
0 NaN Pave 127500
1 2.0 NaN 106000
2 4.0 NaN 178100
3 NaN NaN 140000
缺失值填充后(数值列用均值填充):
NumRooms Alley
0 3.0 Pave
1 2.0 NaN
2 4.0 NaN
3 3.0 NaN
One-Hot编码后的输入特征:
NumRooms Alley_Pave Alley_nan
0 3.0 1.0 0.0
1 2.0 0.0 1.0
2 4.0 0.0 1.0
3 3.0 0.0 1.0
PyTorch输入特征张量 X:
tensor([[3., 1., 0.],
[2., 0., 1.],
[4., 0., 1.],
[3., 0., 1.]], dtype=torch.float64)
PyTorch输出标签张量 y:
tensor([127500, 106000, 178100, 140000])
五、注意
1.在张量(如PyTorch的`Tensor`或NumPy的`ndarray`)操作中,`reshape`方法在满足条件时(元素总数不变且内存布局兼容),会返回原张量的视图(共享底层内存)而非新的拷贝。
在这段代码中: - `b = a.reshape((3,4))` 对`a`进行形状重塑后,`b`与`a`共享同一块内存; - 当执行`b[:] = 2`修改`b`的所有元素时,由于内存共享,`a`的对应元素也会被同步修改。
2.inputs 中包含字符串类型的列(Alley 列,值为 Pave 或 NaN),而调用 inputs.mean() 时会默认对所有列尝试计算均值,字符串列无法计算均值,因此引发类型错误。
# 缺失值填充:数值列(NumRooms)用列均值填充(只对数值列计算均值)
inputs = inputs.fillna(inputs.mean(numeric_only=True)) # 新增 numeric_only=True
六、拓展;jax
说人话就是jax替代numpy成为更先进的高性能数值计算和自动微分的 Python 库
JAX 的核心功能通过以下模块暴露,其中 jax.numpy 是最基础的入口:
jax.numpy:兼容 NumPy 的数组操作,支持 GPU/TPU 加速;
# 基础计算:jax.numpy(兼容 NumPy)
# jax.numpy(简称 jnp)的 API 与 NumPy 几乎完全一致,可直接替换 numpy 实现加速。
#示例:
import jax.numpy as jnp
# 定义数组(默认在GPU/TPU上运行,无需手动指定设备)
x = jnp.array([1, 2, 3])
y = jnp.array([4, 5, 6])
# 基本运算(与NumPy一致)
print(jnp.add(x, y)) # [5 7 9]
print(jnp.dot(x, y)) # 32(内积)
print(jnp.mean(x)) # 2.0(均值)
jax:包含自动微分(grad)、编译(jit)、并行(vmap/pmap)等核心功能;jax.random:生成可复现的随机数(与 NumPy 随机数机制不同)。-
自动微分:
jax.grad与高阶微分
JAX 最核心的功能之一是自动微分,支持一阶、高阶微分,以及前向 / 反向微分。
| 函数 | 用途 | 示例场景 |
|---|---|---|
jax.grad |
反向微分(求梯度),默认返回标量导数 | 神经网络损失函数对参数的梯度 |
jax.jvp |
前向微分(Jacobian-vector 乘积) | 高维输入、低维输出的微分(效率高) |
jax.vjp |
反向模式微分(Vector-Jacobian 乘积) | 低维输入、高维输出的微分 |
jax.hessian |
二阶微分(Hessian 矩阵) | 优化问题中的二阶导数 |
示例 1:用 grad 求函数梯度
import jax
def f(x):
return x**2 + 3 * x
# 用grad求导数函数(f的梯度)
df_dx = jax.grad(f)
print(df_dx(2.0)) # 输出:7.0(与理论一致)
示例 2:高阶微分(梯度的梯度)
def f(x):
return x**3
# 一阶导数:f'(x) = 3x²
df_dx = jax.grad(f)
# 二阶导数:对一阶导数再求导,f''(x) = 6x
d2f_dx2 = jax.grad(df_dx)
print(d2f_dx2(2.0)) # 输出:12.0(6*2=12,正确)
示例 3:多参数函数的微分
def f(x, y):
return x**2 + y * x
# grad默认对第一个参数求导,argnums指定对第几个参数求导
df_dx = jax.grad(f, argnums=0) # 对x求偏导:2x + y
df_dy = jax.grad(f, argnums=1) # 对y求偏导:x
print(df_dx(2.0, 3.0)) # 2*2 + 3 = 7.0
print(df_dy(2.0, 3.0)) # 2.0
此外还有编译加速:jax.jit向量化批量计算:jax.vmap随机数生成:jax.random 多设备并行:jax.pmap,不多赘述
jax代码综合实例:实现简单神经网络
import jax
import jax.numpy as jnp
from jax import grad, jit, vmap
# 1. 定义模型参数(权重和偏置)
def init_params():
key = jax.random.PRNGKey(42)
w1_key, b1_key, w2_key, b2_key = jax.random.split(key, 4)
# 隐层:输入2→64,输出层:64→1
w1 = jax.random.normal(w1_key, (2, 64)) * 0.01
b1 = jax.random.normal(b1_key, (64,)) * 0.01
w2 = jax.random.normal(w2_key, (64, 1)) * 0.01
b2 = jax.random.normal(b2_key, (1,)) * 0.01
return (w1, b1, w2, b2)
# 2. 定义单样本模型(前向传播)
def model(params, x):
w1, b1, w2, b2 = params
x = jnp.dot(x, w1) + b1
x = jax.nn.relu(x) # 激活函数
return jnp.dot(x, w2) + b2
# 3. 用vmap扩展为批量模型(处理多个样本)
batch_model = vmap(model, in_axes=(None, 0)) # 批量处理x(第1个参数)
# 4. 定义损失函数(均方误差)
def loss(params, x, y):
y_pred = batch_model(params, x)
return jnp.mean((y_pred - y)** 2)
# 5. 定义更新函数(梯度下降)
@jit # 编译加速
def update(params, x, y, lr=0.01):
grads = grad(loss)(params, x, y) # 自动求梯度
# 梯度下降更新参数
return tuple(p - lr * g for p, g in zip(params, grads))
# 6. 生成模拟数据(输入x:2维,输出y:1维)
x = jax.random.normal(jax.random.PRNGKey(0), (1000, 2)) # 1000个样本
y = jnp.sum(x * jnp.array([3.0, -2.0]) + 1.5, axis=1, keepdims=True) # 真实关系
# 7. 训练模型
params = init_params()
for epoch in range(1000):
params = update(params, x, y)
if epoch % 100 == 0:
print(f"Epoch {epoch}, Loss: {loss(params, x, y):.4f}")
# 输出结果(接近真实参数3.0, -2.0, 1.5)
print("最终w1(前2列):", params[0][:, :2].T) # 隐层权重(近似真实系数)
输出结果:
Epoch 0, Loss: 22.1060
Epoch 100, Loss: 2.5009
Epoch 200, Loss: 0.4216
Epoch 300, Loss: 0.2505
Epoch 400, Loss: 0.2255
Epoch 500, Loss: 0.1932
Epoch 600, Loss: 0.1517
Epoch 700, Loss: 0.1120
Epoch 800, Loss: 0.0787
Epoch 900, Loss: 0.0537
最终w1(前2列): [[ 0.06903505 -0.00741416]
[ 0.07233214 -0.05622138]]
四年后是不是嵌入式,数字ic和前端好就业一点.....考虑要不要先学嵌入式找个实习保底
鲲鹏昇腾开发者社区是面向全社会开放的“联接全球计算开发者,聚合华为+生态”的社区,内容涵盖鲲鹏、昇腾资源,帮助开发者快速获取所需的知识、经验、软件、工具、算力,支撑开发者易学、好用、成功,成为核心开发者。
更多推荐
所有评论(0)