【AI深度学习基础】NumPy完全指南入门篇:核心功能与工程实践(含完整代码)
一、NumPy简介
NumPy(Numerical Python)是Python中科学计算的核心库,提供了高性能的多维数组对象和各种用于数组操作的函数。它是Python数据分析和科学计算的基础,被广泛应用于机器学习、数据科学、图像处理等领域。其核心优势
在于多维数组(ndarray)的高效操作与向量化运算能力,与Python原生列表相比,ndarray的内存连续性、广播机制和底层C语言优化使其性能提升10-100倍。
1. NumPy核心功能
-
高性能多维数组(ndarray)
NumPy的核心是ndarray
对象,支持高维数据(如向量、矩阵、张量)的高效存储和操作。其内存连续性和C语言底层实现使运算速度远超Python原生列表,尤其适合大规模数据场景。例如,向量化操作无需显式循环即可完成数组间运算。 -
广播机制(Broadcasting)
允许不同形状的数组进行运算,自动扩展维度以匹配计算需求,简化代码并减少内存消耗。例如,在不同形状的数组间进行加法运算时,NumPy会自动将较小的数组扩展为与较大数组形状一致。 -
丰富的数学函数库
提供线性代数(矩阵乘法、求逆)、统计(均值、标准差)、傅里叶变换、随机数生成等函数,覆盖科学计算的全场景。例如: -
内存效率与跨语言集成
数据存储连续且类型一致,内存占用低,同时支持与C/C++/Fortran代码无缝集成,进一步提升计算性能。
2. NumPy在AI学习中的关键作用
-
数据处理与特征工程
- 数据预处理:快速完成缺失值处理、标准化/归一化等操作,为模型输入提供结构化数据。
- 特征构造:通过数组运算生成新特征(如多项式特征、交互项),提升模型表达能力。
-
算法实现与模型训练
- 矩阵运算基础:机器学习算法(如线性回归、神经网络)依赖矩阵乘法、梯度计算等操作,NumPy的高效实现加速模型训练。
- 自定义模型开发:可直接实现K-Means、PCA等算法原型,便于理解底层逻辑。
-
与其他库的协同
- 生态系统基石:Pandas(数据处理)、SciPy(科学计算)、TensorFlow/PyTorch(深度学习)均基于NumPy设计,数据传递无缝衔接。
- GPU加速过渡:NumPy语法与GPU计算库(如CuPy)兼容,便于迁移至高性能计算环境。
3. 优势总结
- 性能优势:C语言内核与向量化操作使计算速度提升10-100倍。
- 代码简洁性:避免显式循环,以声明式语法实现复杂运算。
- 广泛适用性:覆盖科学计算、图像处理、信号分析、金融建模等多领域。
二、NumPy安装指南
1. 安装方式
所有系统通用方法:
# 使用pip安装(推荐)
pip install numpy
# 使用conda安装(适合Anaconda用户)
conda install numpy
验证安装:
import numpy as np
print(np.__version__) # 输出示例:1.24.3
2. 注意事项
- 版本兼容性:确保Python版本≥3.7(NumPy≥1.20要求)
- 加速优化:安装Intel® MKL加速库可提升性能(
conda install numpy mkl
)
三、NumPy基础用法
3.1 数组创建与属性
3.1.1 内容概述
-
数组创建
- 从列表创建:
np.array([1, 2, 3])
- 指定数据类型:
np.array([1, 2, 3], dtype=np.float32)
- 从函数创建:
np.zeros((2, 3))
、np.ones((2, 3))
、np.random.rand(2, 3)
、np.arange(0, 10, 2)
- 从文件读取:
np.loadtxt('data.txt')
- 从内存读取:
np.frombuffer(buffer, dtype=np.float32)
- 从列表创建:
-
数组属性
- 形状(shape):
arr.shape
- 维度(ndim):
arr.ndim
- 元素总数(size):
arr.size
- 数据类型(dtype):
arr.dtype
- 形状(shape):
3.1.2 示例代码
def arr_create_attr():
import numpy as np
# 1.列表创建和常用属性
# 从列表创建一维数组
arr_1d = np.array([1, 2, 3])
# 二维数组
arr_2d = np.array([[1, 2, 3], [4, 5, 6]])
# 查看数据或属性
print('二维数组:', arr_2d)
print(f"形状shape={arr_2d.shape}") # (2, 3)
print(f"维度ndim={arr_2d.ndim}") # 2
print(f"大小size={arr_2d.size}") # 6
print(f"类型dtype={arr_2d.dtype}") # int32
# 使用参数dtype显式指定浮点型
arr_float = np.array([1, 2, 3], dtype=np.float32)
# 强制转换类型(混合数据),使用参数dtype会做数据强制转换
arr_mixed = np.array([1, "2", 3.0], dtype=np.int32)
print('混合类型数组:', arr_mixed) # [1 2 3]
# 2.从函数创建数组
# 全零zeros数组,不支持指定值的全值初始化
arr_zeros = np.zeros((2, 3)) # 2行3列
print('全零数组:', arr_zeros) # [[0. 0. 0.] [0. 0. 0.]]
# 全一数组
arr_ones = np.ones((2, 3))
print('全一数组:', arr_ones) # [[1. 1. 1.] [1. 1. 1.]]
# 随机数组(取值0-1均匀分布)
arr_rand = np.random.rand(2, 3) # 2行3列
print('随机数组:', arr_rand) # [[0.77112162 0.67775043 0.30103794] [0.04624229 0.92962109 0.8566133 ]]
# 等差数列数组
arr_arange = np.arange(1, 10, 3)
print('等差数组:', arr_arange) # [1 4 7]
# 等分数列数组,含端点
arr_linspace = np.linspace(0, 4, 5)
print('等分数组:', arr_linspace) # [0. 1. 2. 3. 4.]
# 3.从文件操作
# csv保存和读取
file_vsv = './data.csv'
dat = np.arange(0, 15).reshape(3, 5)
np.savetxt(file_vsv, dat, delimiter=',')
arr_csv = np.loadtxt(file_vsv, delimiter=',')
print('csv数组:', arr_csv)
# 二进制文件保存和读取
file_dat = './data.npy'
np.save(file_dat, dat)
arr_npy = np.load(file_dat)
print('二进制数组:', arr_npy)
# 4.内存存取
arr_buffer = np.ndarray.tobytes(dat)
arr_buffer = np.frombuffer(arr_buffer, dtype=np.int32)
print('缓存数组:', arr_buffer) # [ 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14]
3.1.3 总结说明
-
灵活多样
- NumPy支持从列表、函数生成、文件、内存等多种数据源创建数组。
-
性能优化
- 使用
zeros
、ones
等函数预分配内存,避免动态扩展开销。
- 使用
-
类型控制
- 通过
dtype
参数可精确控制数据类型,显式指定或强制转换,确保数据一致性,提升计算效率和内存利用率。
- 通过
-
内存布局
- 连续内存布局确保高效内存访问,减少内存碎片和缓存失效。
3.2 数组索引与切片
3.2.1 内容概述
-
一维数组索引
- 整数索引:
arr[0]
- 切片:
arr[1:4]
- 整数索引:
-
多维数组索引
- 整数索引:
arr[0, 1]
- 切片:
arr[:, 1:4]
- 整数索引:
3.2.2 示例代码
def arr_index_slice():
import numpy as np
# 一维数组索引及切片,类似python中的list操作
# 创建一维数组
arr1d = np.arange(0, 5) # [0 1 2 3 4]
# 索引,支持正负数
print(arr1d[0], arr1d[2], arr1d[-1], arr1d[4]) # 0 2 4
# 切片,左闭右开
print(arr1d[2:4]) # [2 3]
print(arr1d[-5:3:2]) # [0 2]
print(arr1d[:]) # [0 1 2 3 4]
print(arr1d[-2:]) # [3 4]
# 二维数组索引及切片
# 创建二维数组
arr2d = np.arange(0, 10).reshape(2, 5) # [[0 1 2 3 4] [5 6 7 8 9]]
# 索引
print(arr2d[0, 0], arr2d[1, 2], arr2d[-1, -1]) # 0 7 9
# 切片,每个维度均可按一维去切片,然后再组合
print(arr2d[:, 1:3]) # [[1 2] [6 7]]
print(arr2d[1, 1:3]) # [6 7]
print(arr2d[:-1, 1:3]) # [[1 2]]
print(arr2d[:-1, 0:5:2]) # [[0 2 4]]
# 高维数组和一维数组转换
a = arr2d.flatten() # 高维转一维
b = np.arange(0, 6).reshape(2, 3) # 一维转二维
3.2.3 总结说明
-
索引规则
- 遵循左闭右开区间原则,如
1:4
包含索引1、2、3 - 负数索引表示从末尾计数,
-1
为最后一个元素
- 遵循左闭右开区间原则,如
-
多维切片语法
- 用逗号分隔维度:
arr[行操作, 列操作]
- 冒号
:
表示全选维度,::步长
控制采样间隔
- 用逗号分隔维度:
-
视图与拷贝
- 切片操作返回原数组视图,修改切片会影响原数组(内存共享)
- 需显式调用
.copy()
创建独立副本:sub_arr = arr[1:4].copy()
-
性能优化
- 避免循环操作,优先使用向量化切片(如
arr[:,1:4]
比逐行遍历快10倍以上) - 对大型数组进行连续切片时,推荐预先计算索引范围减少内存占用
- 避免循环操作,优先使用向量化切片(如
3.3 数组运算
3.3.1 内容概述
-
算术运算
- 加法:
np.add(arr1, arr2)
- 乘法:
np.multiply(arr1, arr2)
- 要点说明:
- 算术运算支持广播机制(不同形状数组自动对齐)
- 逐元素运算与矩阵乘法区分:
*
是逐元素乘,np.dot()
是矩阵乘 - 支持原地运算:
arr1 += 10
直接修改原数组,避免创建新对象
- 加法:
-
统计函数
- 平均值:
np.mean(arr)
- 标准差:
np.std(arr)
- 要点说明:
axis=0
按列计算,axis=1
按行计算- 结合
keepdims=True
保持维度:np.mean(scores, axis=1, keepdims=True)
- 分位数计算:
np.percentile(scores, 75)
- 平均值:
-
线性代数
- 矩阵乘法:
np.dot(arr1, arr2)
- 要点说明:
- 矩阵乘法要求前列数=后行数
- 高级运算包含:求逆(
np.linalg.inv
)、行列式(np.linalg.det
) - 推荐使用
@
运算符简化矩阵乘法表达式
- 矩阵乘法:
-
随机数生成
- 均匀分布:
np.random.rand(2, 3)
- 正态分布:
np.random.randn(2, 3)
- 要点说明:
rand()
生成[0,1)均匀分布,randn()
生成N(0,1)正态分布- 高级分布支持:
np.random.beta
、np.random.poisson
- 生产环境推荐使用
np.random.Generator
对象
- 均匀分布:
3.3.2 示例代码
def arr_index_calc():
import numpy as np
# 1.算术运算
# **要点说明**:
# - 算术运算支持广播机制(不同形状数组自动对齐)
# - 逐元素运算与矩阵乘法区分:`*`是逐元素乘,`np.dot()`是矩阵乘
# - 支持原地运算:`arr1 += 10` 直接修改原数组
# 创建示例数组
arr1 = np.array([[1, 2], [3, 4]])
arr2 = np.array([[5, 6], [7, 8]])
# 逐元素加法
add_result = np.add(arr1, arr2) # 等价于 arr1 + arr2
print("加法结果:\n", add_result)
"""
[[ 6 8]
[10 12]]
"""
# 逐元素乘法
mul_result = np.multiply(arr1, arr2) # 等价于 arr1 * arr2
print("\n乘法结果:\n", mul_result)
"""
[[ 5 12]
[21 32]]
"""
# 2.统计函数
# **要点说明**:
# - `axis=0`按列计算,`axis=1`按行计算
# - 结合`keepdims=True`保持维度:`np.mean(scores, axis=1, keepdims=True)`
# - 分位数计算:`np.percentile(scores, 75)`
# 创建学生成绩数据集
scores = np.array([[85, 90, 78], [76, 88, 92], [90, 85, 80]])
# 全局统计,效果类似于多维变一维
print("全体平均值:", np.mean(scores)) # 84.88888888888889
print("全体标准差:", np.std(scores)) # 5.4046162253401375
# 轴向统计,指定维度方向
print("\n各科平均分:", np.mean(scores, axis=0)) # [83.666 87.666 83.333]
print("学生最高分:", np.max(scores, axis=1)) # [90 92 90]
# 3.线性代数
# **要点说明**:
# - 矩阵乘法要求前列数=后行数
# - 高级运算包含:求逆(`np.linalg.inv`)、行列式(`np.linalg.det`)
# - 推荐使用`@`运算符简化矩阵乘法表达式
# 矩阵乘法
matrix_a = np.array([[1, 2], [3, 4]])
matrix_b = np.array([[5, 6], [7, 8]])
dot_product = np.dot(matrix_a, matrix_b) # 等价于 matrix_a @ matrix_b
print("矩阵乘法结果:\n", dot_product)
"""
[[19 22]
[43 50]]
"""
# 解线性方程组(扩展)
A = np.array([[3, 1], [1, 2]])
b = np.array([9, 8])
x = np.linalg.solve(A, b) # [2., 3.]
# 4.随机数生成
# **要点说明**:
# - `rand()`生成[0,1)均匀分布,`randn()`生成N(0,1)正态分布
# - 高级分布支持:`np.random.beta`、`np.random.poisson`
# - 生产环境推荐使用`np.random.Generator`对象
# 设置随机种子保证可复现
np.random.seed(42)
# 均匀分布[0,1)
uniform_data = np.random.rand(2, 3)
print("均匀分布:\n", uniform_data)
"""
[[0.37454012 0.95071431 0.73199394]
[0.59865848 0.15601864 0.15599452]]
"""
# 标准正态分布
normal_data = np.random.randn(2, 3)
print("\n正态分布:\n", normal_data)
"""
[[ 1.57921282 0.76743473 -0.46947439]
[ 0.54256004 -0.46341769 -0.46572975]]
"""
# 指定范围随机整数
rand_int = np.random.randint(1, 100, (3, 3))
"""
[[76 58 22]
[89 49 91]
[59 42 92]]
"""
3.3.3 总结说明
-
向量化优势
NumPy运算比Python循环快10-100倍,例如对百万级数组求平方耗时对比:# Python列表: ~100ms vs NumPy数组: ~1ms
-
广播机制
允许不同形状数组运算,自动扩展维度:arr = np.array([[1,2],[3,4]]) print(arr + 10) # 所有元素+10
-
内存管理
切片操作生成视图而非副本,修改切片会影响原数组:sub_arr = arr[0:2].copy() # 显式创建副本
-
函数分类
- 数学运算:
sin
,exp
,log
等 - 统计函数:
sum
,median
,percentile
- 线性代数:
svd
,eig
,qr分解
- 数学运算:
-
应用场景
- 机器学习:数据标准化(
(x - mean)/std
) - 科学计算:解微分方程、傅里叶变换
- 图像处理:像素矩阵操作
- 机器学习:数据标准化(
3.4 数组重塑与转置
3.4.1 内容概述
-
重塑
- 改变形状:
arr.reshape((2, 3))
- 展平:
arr.flatten()
- 说明:
reshape
不改变原数组,返回新数组。- 新形状元素总数需与原数组一致,否则报错。
- 可用
-1
自动计算维度(如arr.reshape(3, -1)
)。
- 改变形状:
-
转置
- 行转列:
arr.T
- 说明:
.T
属性是转置的高效实现,返回原数组的视图(共享内存)。- 其他转置方法:
np.transpose(arr)
或np.swapaxes(arr, 0, 1)
。 - 转置后修改视图会影响原数组(需注意内存共享特性)。
flatten()
返回原数组的副本,修改副本不影响原数组。- 若需返回视图(共享内存),可用
ravel()
。
- 行转列:
-
高维转置
- 指定轴顺序:
arr.transpose(1, 0)
- 说明:
- 可同时转置多个维度,如
arr.transpose(2, 0, 1)
。
- 可同时转置多个维度,如
- 指定轴顺序:
3.4.2 示例代码
def arr_reshape():
import numpy as np
# 1.数组重塑(Reshaping)
# 原始数组(1x6)
arr = np.arange(6)
print("原始数组:", arr) # [0 1 2 3 4 5]
# 重塑为2x3矩阵,返回新数组
reshaped = arr.reshape((2, 3))
print("\n重塑后的2x3数组:\n", reshaped)
"""
[[0 1 2]
[3 4 5]]
"""
# 自动推断维度(-1占位符)
auto_reshape = arr.reshape(3, -1) # -1自动计算为2
print("\n自动推断维度结果:\n", auto_reshape)
"""
[[0 1]
[2 3]
[4 5]]
"""
# 展平操作(两种方法)
flattened = reshaped.flatten() # 返回拷贝
raveled = reshaped.ravel() # 返回视图
print("\n展平结果:", flattened) # [0 1 2 3 4 5]
# 2、数组转置(Transpose)
# 创建3x2矩阵
matrix = np.array([[1, 2], [3, 4], [5, 6]])
# 转置方法1:T属性
print("转置结果(T):\n", matrix.T)
"""
[[1 3 5]
[2 4 6]]
"""
# 转置方法2:transpose()函数
print("\n转置结果(transpose):\n", matrix.transpose(1, 0))
"""
[[1 3 5]
[2 4 6]]
"""
# 高维转置(交换轴顺序)
tensor = np.arange(24).reshape(2, 3, 4)
print("\n三维张量转置维度:", tensor.transpose(2, 0, 1).shape) # (4,2,3)
3.4.3 总结说明
-
重塑规则
- 形状匹配:新形状元素总数必须与原数组一致。如
(2,3)
数组只能重塑为(3,2)
、(6,)
等相同元素量的形状 - 维度参数:
reshape()
接受元组参数表示各维度大小,-1
可自动计算维度(如reshape(3,-1)
) - 内存特性:
reshape()
返回视图(共享内存),flatten()
返回副本(独立内存)
- 形状匹配:新形状元素总数必须与原数组一致。如
-
转置方法
- .T属性:最简转置方式,适用于任何维度数组(如三维数组会反转所有轴)
- 轴交换:
transpose()
方法可指定轴顺序(如transpose(1,0)
等效.T) - 特殊转置:
swapaxes(0,1)
可交换指定轴,适用于高维数组调整
-
操作特性
- 视图机制:
reshape
/T
等操作不复制数据,修改视图会影响原数组 - 展平选择:优先使用
flatten()
需要副本时,ravel()
需要视图时 - 维度保持:单行展平可用
reshape(1,-1)
保持二维特性
- 视图机制:
3.5 数组复制与视图
3.5.1 内容概述
-
复制
- 深拷贝:
arr.copy()
- 深拷贝:
-
视图
- 浅拷贝:
arr_view = arr[:]
- 浅拷贝:
3.5.2 示例代码
def arr_copy_view():
import numpy as np
# 1.重塑(视图)
arr = np.arange(6).reshape(2, 3)
arr_reshaped = arr.reshape(3, 2) # 视图操作
arr_reshaped[0, 0] = 100
print("原数组:\n", arr) # 原数组被修改
"""
[[100 1 2]
[ 3 4 5]]
"""
# 2.转置(视图)
arr_transposed = arr.T # 转置生成视图
arr_transposed[0, 1] = 200
print("原数组:\n", arr) # 原数组再次被修改
"""
[[100 1 2]
[200 4 5]]
"""
# 3.深拷贝
arr_copy = arr.copy() # 深拷贝独立内存
arr_copy[0, 0] = 300
print("原数组未改变:\n", arr) # 原数组不受影响
"""
[[100 1 2]
[200 4 5]]
"""
# 4.浅拷贝(视图)
arr_view = arr[:] # 切片生成视图
arr_view[0, 0] = 400
print("原数组被修改:\n", arr) # 数据共享特性
"""
[[400 1 2]
[200 4 5]]
"""
3.5.3 总结说明
-
索引规则
- 遵循左闭右开区间原则,如
1:4
包含索引1、2、3 - 负数索引表示从末尾计数,
-1
为最后一个元素 - 视图通过
base
属性可溯源原始数组(如arr_view.base is arr
返回True)
- 遵循左闭右开区间原则,如
-
多维切片语法
- 用逗号分隔维度:
arr[行操作, 列操作]
- 冒号
:
表示全选维度,::步长
控制采样间隔 - 混合使用整数索引与切片(如
arr[0, ::2]
选取首行偶数列) - 转置操作
.T
或transpose()
生成视图而非副本
- 用逗号分隔维度:
-
内存特性
- 视图共享内存,操作效率高但可能影响原数据
- 深拷贝
.copy()
完全隔离内存,适合需要数据隔离的场景 reshape()
在连续内存时生成视图,否则创建副本
-
性能优化
- 大数据处理优先使用视图避免内存复制
- 显式调用
.copy()
可在视图无法满足需求时强制创建独立副本
NumPy高级用法和性能优化(待续
)
四、NumPy知识点总结
-
核心价值
- NumPy以
ndarray
为核心,实现高性能多维数组运算,速度比Python原生列表快10-100倍 - 广播机制实现不同形状数组的智能运算,减少显式循环和内存复制
- 提供线性代数、统计、随机数生成等完备数学函数库
- NumPy以
-
核心能力
- 数据处理:支持从列表/文件/内存快速构建数组,类型控制精准(dtype)
- 运算体系:向量化运算+广播机制实现零循环代码,内置200+数学函数
- 内存管理:视图机制(reshape/T)避免数据复制,copy()实现深度克隆
- 维度操控:reshape/flatten/transpose满足任意维度变换需求
-
工程实践要点
- 优先使用
arr[::2]
向量化索引替代for
循环 - 利用
arr.reshape(3,-1)
自动计算缺失维度 - 通过
arr.copy()
隔离数据修改风险 - 使用
@
运算符简化矩阵乘法代码
- 优先使用
五、结语
NumPy作为Python科学计算的基石,其高效的多维数组操作和丰富的数学函数库,使其成为AI开发、数据分析、工程计算等领域的核心工具。通过掌握数组创建、向量化运算、广播机制等基础能力,开发者可大幅提升数据处理效率,为机器学习模型训练和算法实现奠定坚实基础。
下篇将介绍NumPy高级用法和性能优化,敬请期待!