我正在处理一些图像数据,因此图像表示为形状为 (1404, 1404, 3) 的 numpy 数组。图像的类型为 np.uint8(它的 RGB 值从 0 到 255)
我想知道这两行代码之间的速度差异:
normalized_image = image.astype("float32") / 255.0
normalized_image = image / np.float32(255)
在 100 个不同的图像上测试这些行后,我得到第一行代码的时间如下:
为什么第二行代码速度这么快?他们不是都在技术上将图像从 uint8 转换为 float32 numpy 数组并执行矢量化除法吗?
我尝试了其他操作顺序,但这似乎有很大差异。有哪位numpy专家知道这个问题的答案吗?
有趣的是,观察到了这两种方法之间的性能差异。虽然是对的,两种方法从根本上都实现了相同的结果,但性能差异很可能源于 NumPy 中类型转换和操作调度 的内部工作原理。
让我们来分析一下发生的事情:
方法 1:
image.astype("float32") / 255.0
-
类型转换:
image.astype("float32")
创建整个图像数组的副本,将其从uint8
转换为float32
。这是需要大量内存和计算时间的操作。 -
除法:
转换后的
float32
数组除以一个float
常量 (255.0)。NumPy 对此进行优化,以对float32
数据执行快速逐元素除法。
方法 2:
image / np.float32(255)
-
混合类型操作:
此处有一个
uint8
数组除以float32
标量。NumPy 在这种情况下会进行 类型广播 ,这意味着它在执行操作之前会将uint8
数组 隐式地 转换为float32
。 - 就地操作: 关键在于,此隐式转换 可能不会 创建原始图像数组的完整副本。为了提高效率,NumPy 可能 会就地执行转换和除法,从而节省时间和内存。
总而言之,性能差异归因于 NumPy 在处理混合类型操作时能够更有效地执行隐式转换和潜在的就地操作。
其他注意事项:
- 实际性能 可能会因 NumPy 版本、硬件和所用图像数据的特定特征而异。
- 为了获得最准确的基准测试,始终建议在的硬件和环境中对两种方法进行分析。
- 在某些情况下,方法 1 可能由于更明确的类型转换而提供更好的可读性,这在处理大型代码库或需要清晰类型处理时可能是有益的。
希望此解释有助于阐明观察到的性能差异!
标签:python,numpy,performance,image-processing,numpy-ndarray From: 78800737