阈值numpy数组的最快方法是什么?

El *_*uso 5 python arrays numpy

我想将结果数组作为二进制是/否.

我想出来了

    img = PIL.Image.open(filename)

    array = numpy.array(img)
    thresholded_array = numpy.copy(array)

    brightest = numpy.amax(array)
    threshold = brightest/2

    for b in xrange(490):
        for c in xrange(490):
            if array[b][c] > threshold:
                thresholded_array[b][c] = 255
            else:
                thresholded_array[b][c] = 0

    out=PIL.Image.fromarray(thresholded_array)
Run Code Online (Sandbox Code Playgroud)

但是一次迭代数组一个值非常慢,我知道必须有一个更快的方法,最快的是什么?

DSM*_*DSM 7

您可以通过多种方式一次比较整个阵列,而不是循环.从...开始

>>> arr = np.random.randint(0, 255, (3,3))
>>> brightest = arr.max()
>>> threshold = brightest // 2
>>> arr
array([[214, 151, 216],
       [206,  10, 162],
       [176,  99, 229]])
>>> brightest
229
>>> threshold
114
Run Code Online (Sandbox Code Playgroud)

方法#1:使用np.where:

>>> np.where(arr > threshold, 255, 0)
array([[255, 255, 255],
       [255,   0, 255],
       [255,   0, 255]])
Run Code Online (Sandbox Code Playgroud)

方法#2:使用布尔索引来创建一个新数组

>>> up = arr > threshold
>>> new_arr = np.zeros_like(arr)
>>> new_arr[up] = 255
Run Code Online (Sandbox Code Playgroud)

方法#3:做同样的事,但使用算术黑客

>>> (arr > threshold) * 255
array([[255, 255, 255],
       [255,   0, 255],
       [255,   0, 255]])
Run Code Online (Sandbox Code Playgroud)

这是因为False == 0True == 1.


对于1000x1000阵列,看起来算术黑客对我来说最快,但说实话我会使用np.where因为我觉得它最清楚:

>>> %timeit np.where(arr > threshold, 255, 0)
100 loops, best of 3: 12.3 ms per loop
>>> %timeit up = arr > threshold; new_arr = np.zeros_like(arr); new_arr[up] = 255;
100 loops, best of 3: 14.2 ms per loop
>>> %timeit (arr > threshold) * 255
100 loops, best of 3: 6.05 ms per loop
Run Code Online (Sandbox Code Playgroud)