当前位置: 首页 > backend >正文

NumPy:数值计算基础与高性能数组操作

NumPy:数值计算基础与高性能数组操作

NumPy 是 Python 科学计算的基础库,提供了高性能的多维数组对象和处理这些数组的工具。它是数据科学、机器学习和科学计算中不可或缺的组件,为 SciPy、Pandas 等库提供了基础支持。本文深入探讨 NumPy 的核心功能和高性能数组操作技巧。

1. NumPy 数组基础

NumPy 的核心是 ndarray 对象,它提供了比 Python 原生列表更高效的数组操作:

import numpy as np# 创建数组的不同方法
arr1 = np.array([1, 2, 3, 4, 5])
arr2 = np.zeros(10)                    # 创建全0数组
arr3 = np.ones((3, 4))                 # 创建全1矩阵
arr4 = np.empty((2, 3, 4))             # 创建未初始化数组
arr5 = np.arange(0, 20, 2)             # 创建指定步长的序列
arr6 = np.linspace(0, 1, 5)            # 创建均匀分布的序列
arr7 = np.random.random((2, 2))        # 创建随机数组# 数组属性
print(f"形状: {arr3.shape}")
print(f"维度: {arr3.ndim}")
print(f"元素类型: {arr3.dtype}")
print(f"元素大小(字节): {arr3.itemsize}")
print(f"元素总数: {arr3.size}")

2. 数组操作与广播机制

NumPy 强大的广播机制使不同形状的数组能够进行运算:

# 基本运算
a = np.array([1, 2, 3])
b = np.array([4, 5, 6])print(a + b)      # 元素级加法: [5, 7, 9]
print(a - b)      # 元素级减法: [-3, -3, -3]
print(a * b)      # 元素级乘法: [4, 10, 18]
print(a / b)      # 元素级除法: [0.25, 0.4, 0.5]
print(a ** 2)     # 元素级平方: [1, 4, 9]
print(np.sqrt(a)) # 元素级平方根: [1., 1.41421356, 1.73205081]# 广播机制示例
matrix = np.ones((3, 3))
vector = np.array([1, 2, 3])# 向量自动广播到矩阵的每一行
result = matrix + vector
print(result)
# 输出:
# [[2. 3. 4.]
#  [2. 3. 4.]
#  [2. 3. 4.]]# 更复杂的广播
a = np.arange(3).reshape((3, 1))
b = np.arange(3)
print(a + b)
# 输出:
# [[0 1 2]
#  [1 2 3]
#  [2 3 4]]

3. 高级索引与切片

NumPy 提供了强大的索引和切片操作,远超 Python 原生列表:

# 创建示例数组
arr = np.arange(10)
print(arr)  # [0 1 2 3 4 5 6 7 8 9]# 基本切片
print(arr[3:8])     # [3 4 5 6 7]
print(arr[1:6:2])   # [1 3 5] - 步长为2# 负索引
print(arr[-3:])     # [7 8 9]
print(arr[-6:-1:2]) # [4 6 8]# 二维数组切片
arr_2d = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
print(arr_2d[1, :])     # 第2行: [4 5 6]
print(arr_2d[:, 1])     # 第2列: [2 5 8]
print(arr_2d[0:2, 1:3]) # 子矩阵: [[2 3], [5 6]]# 布尔索引
mask = arr > 5
print(mask)        # [False False False False False False  True  True  True  True]
print(arr[mask])   # [6 7 8 9]
print(arr[arr > 5]) # 等价操作: [6 7 8 9]# 花式索引
indices = [1, 3, 5, 7]
print(arr[indices])  # [1 3 5 7]# 多维索引
rows = np.array([0, 1])
cols = np.array([1, 2])
print(arr_2d[rows, cols])  # [2 6] - 获取(0,1)和(1,2)位置的元素

4. 数组变形与组合

NumPy 提供了多种操作数组形状和组合数组的方法:

# 变形操作
arr = np.arange(12)
print(arr)             # [ 0  1  2  3  4  5  6  7  8  9 10 11]
arr_reshaped = arr.reshape(3, 4)
print(arr_reshaped)
# [[ 0  1  2  3]
#  [ 4  5  6  7]
#  [ 8  9 10 11]]# 展平数组
flattened = arr_reshaped.ravel()
print(flattened)       # [ 0  1  2  3  4  5  6  7  8  9 10 11]# 转置
transposed = arr_reshaped.T
print(transposed)
# [[ 0  4  8]
#  [ 1  5  9]
#  [ 2  6 10]
#  [ 3  7 11]]# 数组组合
a = np.array([[1, 2], [3, 4]])
b = np.array([[5, 6], [7, 8]])# 垂直堆叠 (行方向)
vertical = np.vstack((a, b))
print(vertical)
# [[1 2]
#  [3 4]
#  [5 6]
#  [7 8]]# 水平堆叠 (列方向)
horizontal = np.hstack((a, b))
print(horizontal)
# [[1 2 5 6]
#  [3 4 7 8]]# 沿新轴堆叠
depth = np.dstack((a, b))
print(depth)
# [[[1 5]
#   [2 6]]
#  [[3 7]
#   [4 8]]]# 沿指定轴连接
concat = np.concatenate((a, b), axis=0)  # 等同于vstack
print(concat)

5. 向量化操作与性能优化

NumPy 的核心优势在于向量化操作,避免使用 Python 循环:

import time
import numpy as np# 创建大数组
size = 1000000
data = np.random.random(size)# Python循环方式计算平方和
start = time.time()
sum_squares = 0
for x in data:sum_squares += x ** 2
python_time = time.time() - start
print(f"Python循环结果: {sum_squares:.6f}, 耗时: {python_time:.6f}秒")# NumPy向量化方式计算
start = time.time()
sum_squares_np = np.sum(data ** 2)
numpy_time = time.time() - start
print(f"NumPy向量化结果: {sum_squares_np:.6f}, 耗时: {numpy_time:.6f}秒")
print(f"加速比: {python_time/numpy_time:.1f}倍")# 避免复制的操作
a = np.arange(1e6)
# 视图 - 不创建新数组
b = a.view()
print(b is a)  # False
print(b.base is a)  # True
b[0] = 999
print(a[0])  # 999 - 原数组也被修改# 副本 - 创建新数组
c = a.copy()
print(c.base is a)  # False
c[0] = 0
print(a[0])  # 999 - 原数组不变

6. 数学函数与统计操作

NumPy 提供了丰富的数学和统计函数:

# 创建测试数组
data = np.random.normal(0, 1, 1000)  # 均值0, 标准差1的正态分布# 基本统计
print(f"最小值: {np.min(data):.4f}")
print(f"最大值: {np.max(data):.4f}")
print(f"均值: {np.mean(data):.4f}")
print(f"中位数: {np.median(data):.4f}")
print(f"标准差: {np.std(data):.4f}")
print(f"方差: {np.var(data):.4f}")
print(f"总和: {np.sum(data):.4f}")# 按轴计算统计量
arr_2d = np.random.randint(0, 10, (3, 4))
print(arr_2d)
print(f"行和: {np.sum(arr_2d, axis=1)}")
print(f"列和: {np.sum(arr_2d, axis=0)}")
print(f"行最大值: {np.max(arr_2d, axis=1)}")
print(f"列最大值: {np.max(arr_2d, axis=0)}")# 累计函数
print(f"累积和: {np.cumsum(np.arange(10))}")
print(f"累积积: {np.cumprod(np.arange(1, 5))}")# 数学函数
angles = np.linspace(0, np.pi, 5)
print(f"角度: {angles}")
print(f"正弦: {np.sin(angles)}")
print(f"余弦: {np.cos(angles)}")
print(f"正切: {np.tan(angles)}")
print(f"对数: {np.log(np.arange(1, 6))}")
print(f"指数: {np.exp(np.arange(5))}")

7. 线性代数运算

NumPy 内置了基本的线性代数功能:

# 创建矩阵
A = np.array([[1, 2], [3, 4]])
B = np.array([[5, 6], [7, 8]])# 矩阵乘法
C1 = A.dot(B)
C2 = A @ B  # Python 3.5+ 的矩阵乘法运算符
print(C1)
print(C2)# 矩阵转置
print(A.T)# 计算行列式
det_A = np.linalg.det(A)
print(f"行列式: {det_A}")# 求逆矩阵
inv_A = np.linalg.inv(A)
print(f"逆矩阵:\n{inv_A}")
print(f"验证 A @ A^-1 ≈ I:\n{A @ inv_A}")# 求解线性方程组 Ax = b
b = np.array([1, 2])
x = np.linalg.solve(A, b)
print(f"方程组解: {x}")
print(f"验证 A @ x ≈ b: {A @ x}")# 特征值和特征向量
eigenvalues, eigenvectors = np.linalg.eig(A)
print(f"特征值: {eigenvalues}")
print(f"特征向量:\n{eigenvectors}")# 奇异值分解 (SVD)
U, s, Vh = np.linalg.svd(A)
print(f"奇异值: {s}")# 矩阵范数
print(f"矩阵F范数: {np.linalg.norm(A, 'fro')}")
print(f"矩阵2范数: {np.linalg.norm(A, 2)}")

8. 随机数生成

NumPy 提供了强大的随机数生成功能:

# 设置随机种子以确保结果可重现
np.random.seed(42)# 均匀分布
uniform_samples = np.random.random(5)  # [0, 1)之间的均匀分布
print(f"均匀分布样本: {uniform_samples}")# 正态分布
normal_samples = np.random.normal(0, 1, 5)  # 均值0, 标准差1
print(f"正态分布样本: {normal_samples}")# 整数随机数
int_samples = np.random.randint(1, 100, 5)  # 1到99之间的整数
print(f"整数随机样本: {int_samples}")# 随机排列
arr = np.arange(10)
np.random.shuffle(arr)  # 原地打乱
print(f"随机打乱后: {arr}")# 随机选择
choices = np.random.choice(arr, size=5, replace=False)  # 不重复抽样
print(f"随机选择: {choices}")# 多维随机数组
rand_2d = np.random.rand(3, 4)  # 3x4的[0,1)均匀分布
print(f"2D均匀分布:\n{rand_2d}")# 随机置换
orig = np.arange(10)
perm = np.random.permutation(orig)  # 返回随机排列的副本
print(f"原数组: {orig}")
print(f"随机置换: {perm}")# 设置新的随机数生成器 (numpy 1.17+)
rng = np.random.default_rng(seed=12345)
print(f"新生成器样本: {rng.random(5)}")

9. 文件操作与数据处理

NumPy 提供了多种文件读写格式支持:

# 创建示例数据
data = np.random.randn(5, 4)
print(f"原始数据:\n{data}")# 保存为numpy格式
np.save('data.npy', data)
# 加载numpy格式
loaded_data = np.load('data.npy')
print(f"从.npy加载:\n{loaded_data}")# 保存为文本格式
np.savetxt('data.csv', data, delimiter=',', fmt='%.6f')
# 从文本加载
txt_data = np.loadtxt('data.csv', delimiter=',')
print(f"从CSV加载:\n{txt_data}")# 保存多个数组
x = np.arange(10)
y = np.random.random(10)
np.savez('multiple_arrays.npz', x=x, y=y)
# 加载多个数组
loaded = np.load('multiple_arrays.npz')
print(f"加载的x: {loaded['x']}")
print(f"加载的y: {loaded['y']}")# 内存映射文件 - 适用于超大数组
mmap_array = np.memmap('mmap_file.dat', dtype='float32', mode='w+', shape=(3, 4))
mmap_array[:] = np.random.random((3, 4))
mmap_array.flush()  # 写入磁盘# 重新加载内存映射
mmap_loaded = np.memmap('mmap_file.dat', dtype='float32', mode='r', shape=(3, 4))
print(f"内存映射数组:\n{mmap_loaded}")

10. 实际应用案例:图像处理

NumPy 在图像处理中的基本应用:

# 需要安装Pillow库: pip install Pillow
from PIL import Image
import numpy as np
import matplotlib.pyplot as plt# 创建一个简单的图像数组
img_array = np.zeros((300, 400, 3), dtype=np.uint8)
img_array[50:250, 50:350, 0] = 255  # 红色通道
img_array[100:200, 100:300, 1] = 255  # 绿色通道# 将NumPy数组转换为PIL图像
img = Image.fromarray(img_array)
img.save('generated_image.png')# 读取图像并转换为NumPy数组
try:loaded_img = Image.open('generated_image.png')loaded_array = np.array(loaded_img)# 图像处理 - 水平翻转flipped = loaded_array[:, ::-1, :]# 图像处理 - 提取一个通道red_channel = loaded_array[:, :, 0]# 图像处理 - 旋转90度rotated = np.rot90(loaded_array)# 图像处理 - 调整亮度brighter = np.clip(loaded_array * 1.5, 0, 255).astype(np.uint8)# 显示结果plt.figure(figsize=(12, 8))plt.subplot(2, 2, 1)plt.imshow(loaded_array)plt.title('原始图像')plt.axis('off')plt.subplot(2, 2, 2)plt.imshow(flipped)plt.title('水平翻转')plt.axis('off')plt.subplot(2, 2, 3)plt.imshow(red_channel, cmap='Reds')plt.title('红色通道')plt.axis('off')plt.subplot(2, 2, 4)plt.imshow(brighter)plt.title('增加亮度')plt.axis('off')plt.tight_layout()plt.savefig('image_processing_result.png')except FileNotFoundError:print("无法找到图像文件,请确保路径正确")
except Exception as e:print(f"处理图像时出错: {e}")

结论

NumPy 是 Python 科学计算的基石,提供了高性能的多维数组对象和丰富的数学函数库。通过使用 NumPy,您可以显著提高数据处理和科学计算的效率,特别是在处理大规模数据时。

本文仅涵盖了 NumPy 的核心功能,实际应用中 NumPy 与其他库(如 SciPy、Pandas、Matplotlib)结合使用,可以构建强大的数据分析和科学计算工作流。掌握 NumPy 是进入 Python 科学计算领域的重要一步。

http://www.xdnf.cn/news/672.html

相关文章:

  • 如何使用人工智能大模型,免费快速写工作总结?
  • Linux基础指令 补充(自用)
  • 【微知】服务器如何获取服务器的SN序列号信息?(dmidecode -t 1)
  • Origin将双Y轴柱状图升级为双向分组柱状图
  • 二、在springboot 中使用 AIService
  • 【JAVA EE初阶】多线程(1)
  • 代码随想录算法训练营第五十三天 | 105.有向图的完全可达性 106.岛屿的周长
  • 如何轻松实现用户充值系统的API自动化测试
  • QML、Qt Quick 、Qt Quick Controls 2
  • 如何成为Prompt工程师:学习路径、核心技能与职业发展
  • STM32时钟树
  • 微信小程序中使用h5页面预览图片、视频、pdf文件
  • PHP伪协议读取文件
  • Matlab 步进电机传递函数模糊pid
  • langchain-nextjs-template 模板安装与配置
  • 【文献阅读】EndoNet A Deep Architecture for Recognition Tasks on Laparoscopic Videos
  • 【MRAG】使用RAG技术增强AI回复的实时性和准确性
  • Android Kotlin AIDL 完整实现与优化指南
  • Leetcode 3524. Find X Value of Array I
  • 9、Hooks:现代魔法咒语集——React 19 核心Hooks
  • 山东大学软件学院项目实训-基于大模型的模拟面试系统-Token过期重定向问题
  • 代码随想录算法训练营第三十五天|416. 分割等和子集、698.划分为k个相等的子集、473.火柴拼正方形
  • IDEA连接达梦数据库
  • Android学习之实战登录注册能力
  • Django 使用教程
  • 4月19日记(补)算了和周日一块写了 4月20日日记
  • 无法右键下载文档?网页PDF下载方法大全
  • Python赋能去中心化电子商务平台:重构交易生态的新未来
  • 2000-2017年各省天然气消费量数据
  • uni-app中map的使用