目录

一、数据创建与存储模块

二、Pandas 数据处理模块

三、PyTorch 张量转换模块

五、注意

六、拓展;jax


一、数据创建与存储模块
  • os.makedirs(path, exist_ok=True)

    • 作用:创建多级目录,避免手动逐层创建的繁琐;exist_ok=True保证目录已存在时不报错。
    • 使用场景:数据文件存储前的目录预处理。
  • os.path.join(part1, part2, ...)

    • 作用:跨平台拼接文件路径(自动适配 Windows 的\和 Linux/macOS 的/)。
    • 使用场景:确保路径在不同操作系统下的兼容性。
  • 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=TrueNaN视为独立类别;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和前端好就业一点.....考虑要不要先学嵌入式找个实习保底

Logo

鲲鹏昇腾开发者社区是面向全社会开放的“联接全球计算开发者,聚合华为+生态”的社区,内容涵盖鲲鹏、昇腾资源,帮助开发者快速获取所需的知识、经验、软件、工具、算力,支撑开发者易学、好用、成功,成为核心开发者。

更多推荐