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

网站图片一般分辨率做多大赣州网站建设服务

网站图片一般分辨率做多大,赣州网站建设服务,个人网站用什么域名好,ui设计是什么专业学的NumPy高级技巧:向量化、广播与einsum的高效使用摘要 NumPy 是 Python 科学计算生态的基石,但仅仅会用 np.array 是远远不够的。要从“能用”到“精通”,释放 NumPy 的全部计算潜能,就必须掌握其三大核心利器:向量化 (V…

NumPy高级技巧:向量化、广播与einsum的高效使用

在这里插入图片描述


摘要

NumPy 是 Python 科学计算生态的基石,但仅仅会用 np.array 是远远不够的。要从“能用”到“精通”,释放 NumPy 的全部计算潜能,就必须掌握其三大核心利器:向量化 (Vectorization)广播 (Broadcasting)爱因斯坦求和 (einsum)。本文将通过生动的实例和性能对比,带你深入理解这三个高级技巧,助你写出更简洁、更高效、更具“NumPy风格”的代码,告别低效的 Python 循环。


1. 向量化 (Vectorization):性能的源泉

什么是向量化? 简单来说,就是直接对整个数组(或多个数组)进行运算,而不是通过显式的 for 循环遍历每个元素。这些运算在 NumPy 的底层由高度优化的 C 或 Fortran 代码执行。

为什么向量化如此之快?

  1. 预编译的 C 代码: NumPy 的底层函数是预编译的 C 代码,执行速度远超 Python 解释器逐行解释执行的速度。
  2. SIMD (单指令多数据流): 底层库(如 BLAS, LAPACK)能充分利用现代 CPU 的 SIMD 指令集,实现真正的并行计算,一个 CPU 指令可以同时处理多个数据。
  3. 内存访问优化: 向量化操作能更有效地利用 CPU 缓存,减少内存访问的延迟。

性能对比:循环 vs. 向量化

让我们通过一个简单的例子直观感受一下性能差距。假设我们需要计算一个大数组中每个元素的 sin 值。

import numpy as np
import time# 创建一个包含一百万个元素的大数组
large_array = np.arange(1_000_000)# 方法一:使用 Python 的 for 循环
start_time = time.time()
result_loop = [np.sin(x) for x in large_array]
end_time = time.time()
print(f"Python for 循环耗时: {end_time - start_time:.6f} 秒")# 方法二:使用 NumPy 向量化
start_time = time.time()
result_vectorized = np.sin(large_array)
end_time = time.time()
print(f"NumPy 向量化耗时:  {end_time - start_time:.6f} 秒")# 在 IPython 或 Jupyter 环境中,推荐使用 %timeit 魔法命令进行更精确的性能测试
# %timeit [np.sin(x) for x in large_array]
# %timeit np.sin(large_array)

输出结果(示例):

Python for 循环耗时: 0.312345 秒
NumPy 向量化耗时:  0.009876 秒

结论: 在这个例子中,向量化操作的速度是 for 循环的 30倍 以上!在数据科学和机器学习中,这种性能差异至关重要。


2. 广播 (Broadcasting):优雅的维度扩展

什么是广播? 广播是 NumPy 在处理不同形状(shape)的数组进行算术运算时的一套规则。它允许 NumPy 在无需实际复制数据的情况下,“虚拟地”扩展较小数组的维度,使其与较大数组的形状兼容。

广播的核心规则

当两个数组进行运算时,NumPy 会从两个数组的 尾部维度(从右到左)开始比较它们的形状。

  1. 规则一:维度兼容

    • 如果两个维度的大小 相等,则该维度是兼容的。
    • 如果其中一个维度的大小是 1,则该维度也是兼容的。
    • 除此之外,维度 不兼容,NumPy 会抛出 ValueError
  2. 规则二:维度扩展

    • 如果两个数组的维度数量不同,NumPy 会在维度较少的数组的 左侧 补 1,直到它们的维度数量相同。
    • 在任何维度上,如果一个数组的大小是 1,另一个数组的大小大于 1,那么大小为 1 的数组会沿着该维度进行“拉伸”以匹配另一个数组的形状。

广播实例解析

示例 1: 数组与标量
a = np.array([1, 2, 3])  # Shape: (3,)
b = 100                  # 标量
result = a + b           # b 被广播到 [100, 100, 100]
print(result)            # 输出: [101 102 103]
示例 2: 二维数组与一维数组
A = np.arange(1, 10).reshape(3, 3) # Shape: (3, 3)
v = np.array([10, 20, 30])         # Shape: (3,)# A 的 shape 是 (3, 3)
# v 的 shape 是 (3,)
# 规则二:v 的 shape 在左侧补1,变为 (1, 3)
# 比较 (3, 3) 和 (1, 3):
# - 尾维度:3 == 3 (兼容)
# - 前一维度:3 vs 1 (兼容),v 的维度 1 被拉伸到 3
# 最终 v 被广播成 [[10, 20, 30], [10, 20, 30], [10, 20, 30]]
result = A + v
print(result)
# 输出:
# [[11 22 33]
#  [14 25 36]
#  [17 28 39]]
示例 3: 列向量与行向量相加

这是一个非常强大的应用,可以快速生成坐标网格。

col_vec = np.array([0, 10, 20, 30]).reshape(4, 1) # Shape: (4, 1)
row_vec = np.array([0, 1, 2])                     # Shape: (3,)# col_vec 的 shape 是 (4, 1)
# row_vec 的 shape 是 (3,)
# 规则二:row_vec 的 shape 在左侧补1,变为 (1, 3)
# 比较 (4, 1) 和 (1, 3):
# - 尾维度:1 vs 3 (兼容),col_vec 的维度 1 被拉伸到 3
# - 前一维度:4 vs 1 (兼容),row_vec 的维度 1 被拉伸到 4
result = col_vec + row_vec
print(result)
# 输出:
# [[ 0  1  2]
#  [10 11 12]
#  [20 21 22]
#  [30 31 32]]

⚠️ 注意: 广播是一种高效的机制,因为它并 在内存中创建扩展后的大数组,而是通过巧妙的索引计算来实现的,因此内存效率极高。


3. einsum:NumPy 的瑞士军刀

np.einsum (爱因斯坦求和约定) 是 NumPy 中最强大、最灵活的函数之一。它使用一种简洁的字符串“迷你语言”来表示复杂的多维数组(张量)运算。

einsum 的语法: np.einsum('下标字符串', a, b, ...)

  • 下标字符串 定义了输入和输出数组的维度关系。
  • 逗号 , 用于分隔不同的输入数组。
  • 箭头 -> 用于分隔输入和输出的下标。
  • 重复的下标 意味着沿该维度进行求和(或收缩)。
  • 未在输出中出现的下标 也会被求和。

einsum 实例解析

A = np.arange(1, 5).reshape(2, 2)   # [[1, 2], [3, 4]]
B = np.arange(5, 9).reshape(2, 2)   # [[5, 6], [7, 8]]
v = np.array([10, 20])
1. 矩阵乘法 (ij,jk->ik)
# A(i,j) @ B(j,k) -> C(i,k)
# j 是重复下标,表示沿该维度求和
C = np.einsum('ij,jk->ik', A, B)
print("矩阵乘法:", C)
# 等价于 np.matmul(A, B) 或 A @ B
2. 向量点积 (i,i->)
# v(i) * v(i) -> 标量
# i 是重复下标,表示求和。输出为空,表示结果是标量。
dot_product = np.einsum('i,i->', v, v)
print("\n向量点积:", dot_product)
# 等价于 np.dot(v, v)
3. 矩阵转置 (ij->ji)
# A(i,j) -> A_T(j,i)
# 只是简单地交换了维度顺序
transpose_A = np.einsum('ij->ji', A)
print("\n矩阵转置:", transpose_A)
# 等价于 A.T
4. 沿轴求和 (ij->i)
# A(i,j) -> v(i)
# j 没有出现在输出中,表示沿 j 轴求和
sum_axis_1 = np.einsum('ij->i', A)
print("\n沿轴1求和:", sum_axis_1)
# 等价于 np.sum(A, axis=1)
5. 矩阵的迹 (ii->)
# A(i,i) -> 标量
# 重复的 i 表示只取对角线元素,输出为空表示对它们求和
trace_A = np.einsum('ii->', A)
print("\n矩阵的迹:", trace_A)
# 等价于 np.trace(A)

为什么使用 einsum

  • 可读性: 对于复杂的多维张量运算,einsum 的字符串表示法比一长串的 transpose, reshape, sum 操作更清晰。
  • 性能: einsum 内部有优化路径,可以智能地选择最优计算顺序,有时能避免产生巨大的中间数组,从而节省内存并提高速度。

总结

精通 NumPy 的关键在于从命令式(“怎么做”的 for 循环思维,转向声明式(“做什么”)的数组思维。向量化、广播和 einsum 正是实现这一转变的强大工具。

  • 向量化 是基础,永远优先使用 NumPy 的内置函数来替代 Python 循环。
  • 广播 是处理不同形状数组的优雅方式,务必掌握其规则,它能让你的代码更简洁。
  • einsum 是处理复杂线性代数和张量运算的终极武器,虽然初看有些晦涩,但一旦掌握,将极大提升你的代码表达力和性能。

希望这篇教程能帮助你更上一层楼。如果觉得文章不错,欢迎 点赞、收藏、关注


拓展工具与服务推荐

当你在处理复杂的数据科学问题,或者需要为你的应用寻找稳定、高性价比的 AI 模型 API 时,不妨考虑以下服务:

  • AI 编程助手:https://0v0.pro 是一个强大的编程伙伴,它集成了多种先进的 AI 模型,可以帮你生成 NumPy 代码、解释 einsum 表达式,甚至调试复杂的算法逻辑。

http://www.dtcms.com/a/504969.html

相关文章:

  • 2017招远网站建设云兰装潢公司总部地址电话
  • 网站服务器查询工具wordpress 返回顶部插件
  • 做网站推广弊端青岛胶南做网站的
  • 2018年网站建设工作总结北京市建设工程信息网登录流程
  • 网站首页背景代码旅游类网站开发毕业设计
  • 9 垂直分片
  • 公司网站如何备案如何制作钓鱼网站
  • 做网站如何分类关于网站建设的外文翻译
  • 网站建设申请书搜了网推广
  • 昆明做网站建设有哪些网站推广优化联系方式
  • 免费注册自己的网站品牌建设卓有成效
  • 易语言和网站做交互中国赣州
  • 网站网页设计制作公司搬家网站建设案例说明
  • STM32Cubemx配置独立看门狗(IWDG)
  • 有做翻译英文网站山西网站开发二次开发
  • 外贸业务怎么利用网站开发客户网站建设模板网站
  • 免费的企业网站建设wordpress做漫画
  • 网站域名查询网网站推广的方法搜索引擎
  • 给外国小孩 做 英语题用的网站怎么做文学动漫网站
  • 网站制作网页设计室内设计软件3d
  • 北京专业制作网站公司哪家好贵南网站建设
  • 浙江人工智能建站系统软件网站页脚写什么
  • 公司网站怎么更新需要怎么做优化关键词哪家好
  • 简单的企业网站外贸网站广告宣传网站
  • 网站建设提供商wordpress next
  • 湖州北京网站建设定制手机网站建设
  • 深圳专门做网站WordPress如何快速排名
  • 网站建设公司 lnmp建造官网
  • 丹阳建站asp 网站图标
  • 无锡网站推广哪家好网站维护工作