我有一个形状(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)

现在,我想将imgmaxa进行比较,我知道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返回值;不用于将==与数组一起使用。