我有一个形状(height, width, 3)
的three-dimensional阵列,它表示一个BGR映像,值是[0,1]中的浮动。
在像素上进行了一些操作后,我获得了形状(height, width)
的two-dimensional阵列,阵列中的值是对每个单独像素上执行的某些操作的结果。
现在,我想将原始image与结果进行比较,更具体地说,我想将每个像素的每个BGR组件与位于同一坐标处的结果数组的值进行比较。
例如,我想知道每个像素中哪个是哪个BGR组件:
import numpy as np
img = np.random.random((360, 640, 3))
maxa = img.max(axis=-1)
现在,我想将img
与maxa
进行比较,我知道img == maxa
不起作用:
In [335]: img == maxa
<ipython-input-335-acb909814b9a>:1: DeprecationWarning: elementwise comparison failed; this will raise an error in the future.
img == maxa
Out[335]: False
我不擅长描述事物,所以我会向您展示我打算在Python中做的事情:
result = [[[c == maxa[y, x] for c in img[y, x]] for x in range(640)] for y in range(360)]
显然,它效率低下,但我想证明我知道逻辑。
我已经在numpy中做了同样的事情,但我认为这可以更有效:
img == np.dstack([maxa, maxa, maxa])
我已经确认了我的理解的正确性:
In [339]: result = [[[c == maxa[y, x] for c in img[y, x]] for x in range(640)] for y in range(360)]
...: np.array_equal(arr3, img == np.dstack([maxa, maxa, maxa]))
Out[339]: True
我已经基准了我的方法:
In [340]: %timeit [[[c == maxa[y, x] for c in img[y, x]] for x in range(640)] for y in range(360)]
509 ms ± 16.6 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
In [341]: maxals = maxa.tolist()
In [342]: imgls = img.tolist()
In [343]: %timeit [[[c == maxals[y][x] for c in imgls[y][x]] for x in range(640)] for y in range(360)]
156 ms ± 2.57 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)
In [344]: %timeit img == np.dstack([maxa, maxa, maxa])
4.25 ms ± 121 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
什么是更快的方法?
分析解答
如果这是您想要的:
img == np.dstack([maxa, maxa, maxa])
那就是你的做法:
img == maxa[..., np.newaxis]
Numpy广播规则意味着添加了外部维度as-required,而不是内部维度。这意味着您可以将形状[x, y, z]
与形状[y, z]
进行比较(对于所有x
,做...),但不能比较[x, y]
(对于所有z
,DO…)。但是,可以将内部维度设置为1,从而允许适当的广播。这就是我们对np.newaxis
的作用。它将[x, y]
形状变成[x, y, 1]
。
弃用警告仅是为了比较不兼容的形状阵列并获得False
返回值;不用于将==
与数组一起使用。