首页 > 编程问答 >为什么用 numpy 数组除以 float32 常量比将 numpy 数组转换为 float32 然后除法更快?

为什么用 numpy 数组除以 float32 常量比将 numpy 数组转换为 float32 然后除法更快?

时间:2024-07-27 14:58:45浏览次数:13  
标签:python numpy performance image-processing numpy-ndarray

我正在处理一些图像数据,因此图像表示为形状为 (1404, 1404, 3) 的 numpy 数组。图像的类型为 np.uint8(它的 RGB 值从 0 到 255)

我想知道这两行代码之间的速度差异:

normalized_image = image.astype("float32") / 255.0 
normalized_image = image / np.float32(255)

在 100 个不同的图像上测试这些行后,我得到第一行代码的时间如下: first line of code

至于第二行代码: enter image description here

为什么第二行代码速度这么快?他们不是都在技术上将图像从 uint8 转换为 float32 numpy 数组并执行矢量化除法吗?

我尝试了其他操作顺序,但这似乎有很大差异。有哪位numpy专家知道这个问题的答案吗?


有趣的是,观察到了这两种方法之间的性能差异。虽然是对的,两种方法从根本上都实现了相同的结果,但性能差异很可能源于 NumPy 中类型转换和操作调度 的内部工作原理。

让我们来分析一下发生的事情:

方法 1: image.astype("float32") / 255.0

  1. 类型转换: image.astype("float32") 创建整个图像数组的副本,将其从 uint8 转换为 float32 。这是需要大量内存和计算时间的操作。
  2. 除法: 转换后的 float32 数组除以一个 float 常量 (255.0)。NumPy 对此进行优化,以对 float32 数据执行快速逐元素除法。

方法 2: image / np.float32(255)

  1. 混合类型操作: 此处有一个 uint8 数组除以 float32 标量。NumPy 在这种情况下会进行 类型广播 ,这意味着它在执行操作之前会将 uint8 数组 隐式地 转换为 float32
  2. 就地操作: 关键在于,此隐式转换 可能不会 创建原始图像数组的完整副本。为了提高效率,NumPy 可能 会就地执行转换和除法,从而节省时间和内存。

总而言之,性能差异归因于 NumPy 在处理混合类型操作时能够更有效地执行隐式转换和潜在的就地操作。

其他注意事项:

  • 实际性能 可能会因 NumPy 版本、硬件和所用图像数据的特定特征而异。
  • 为了获得最准确的基准测试,始终建议在的硬件和环境中对两种方法进行分析。
  • 在某些情况下,方法 1 可能由于更明确的类型转换而提供更好的可读性,这在处理大型代码库或需要清晰类型处理时可能是有益的。

希望此解释有助于阐明观察到的性能差异!

标签:python,numpy,performance,image-processing,numpy-ndarray
From: 78800737

相关文章

  • 太强了,Python+Excel真的是神仙组合!
    本书是由流行开源Python库xlwings的创始人:费利克斯·朱姆斯坦(FelixZumstein)所撰写。他详细阐述了如何将Python与Excel结合使用,让任务自动化,从而实现效率飞跃。为了帮助初学者克服对Python的恐惧,作者特意将教程内容设计成从简单到复杂的顺序进行介绍。这本书PDF共282页,分为4个......
  • 在 Python 中获取精确的 Android GPS 位置
    我尝试在Python中获取Android手机的GPS位置(使用QPython3应用程序)。这种可行,但是Android中似乎有几个LocationProvider:gps:纯gps定位,速度慢,耗能,但非常准确,正是我所需要的。网络:GPS和wifi/小区定位的混合,更快,但不太准确被动......
  • 使用 docker run 将 Python 单击选项传递给 ENTRYPOINT 会出现错误:“在 $PATH 中找不
    我有一个简单的python脚本,我想在docker容器内运行它。它打印一行消息“Hello{name}”。python脚本使用clickCLI界面来定义收件人名称,如果我直接运行它(不使用dockerrun命令),它将如下所示:pythonhello.py-nSmithDockerbuild命令:dockerbuild.-thello:1.......
  • 标题:在 OpenSees Python 中定义具有特定卸载行为的双线性弹塑性材料
    我正在使用Python中的OpenSees,我想定义一种在负载下表现出双线性弹塑性行为的材料。但是,我需要在卸载过程中将材质返回到其原始位置,遵循准确的加载路径。在此处输入图像描述我不确定如何在OpenSees中正确实现卸载行为,我正在寻找实现这一具体材料反应的指导。......
  • 使用正则表达式删除Python中常见的公司名称后缀
    我正在努力删除一些公司名称中的后缀。预期结果如下:原始名称:AppleInc.SonyCorporationFiatChryslerAutomobilesS.p.A.SamsungElectronicsCo.,Ltd.清除名称:AppleSonyFiatChryslerAutomobilesSamsungElectronics到目前为止我所做的:importred......
  • 如何将 Brave 网络浏览器与 python、selenium 和 chromedriver 结合使用?
    我从Google的Chrome切换到Brave网络浏览器并且很难让它像Chrome一样与Brave一起使用。Brave是基于Chromium的,所以我猜它应该不会那么难。我确保我的Brave和Chromedriver处于相同版本,像这样,~/some/path$chromedriver--versionChromeDriver76.0.3......
  • 覆盖 python 应用程序时权限被拒绝
    我使用python制作了一个粗略的自动更新应用程序,并使用freeze-cx制作了exe文件。首先,该应用程序检查firebase服务器上是否有最新版本的文件可用,如果可用则下载zip文件。并且应用程序解压并覆盖文件。this_file_path=sys.executableifgetattr(sys,'frozen......
  • Python数据分析案例55——基于LSTM结构自编码器的多变量时间序列异常值监测
    案例背景时间序列的异常值检测是方兴未艾的话题。比如很多单变量的,一条风速,一条用电量这种做时间序列异常值检测,想查看一下哪个时间点的用电量异常。多变量时间序列由不同变量随时间变化的序列组成,这些时间序列在实际应用中通常来自不同的传感器或数据源。多变量时间序列异......
  • 为什么我检查了 numpy、scikitlearn 和 scipy 的版本号却无法安装 NLTK?
    我运行了代码importnltkfromnltk.stemimportPorterStemmerfromnltk.tokenizeimportword_tokenizenltk.download('punkt')如果我运行我的代码,我会看到以下内容:File"sklearn/utils/murmurhash.pyx",line1,initsklearn.utils.murmurhashValueError:nu......
  • 我没有 python 但我有 python3
    我最近格式化了我的笔记本电脑并安装了Ubuntu操作系统。我没有明确安装Python。为了检查它是否已预安装,我在终端中运行python--version并得到了这个:$python--versionCommand'python'notfound,butcanbeinstalledwith:sudoaptinstallpython3......