There are two arrays. With two for loops, I bypass the first array, based on the data from which I fill in the second. If the array is large, the program runs for a very long time. Tell me how to accelerate the traversal of the array (using standard tools or numpy, for example).

white = (255, 255, 255) black = (0, 0, 0) array = np.full((img.shape[0], img.shape[1], 3), black, dtype='uint8') for i in range (img.shape[0]): for j in range (img.shape[1]): if (img[i, j] == True): array[i, j, :] = white 
  • Please indicate the shape arrays: img and array - MaxU
  • because the values ​​of the array do not depend on the previous (next) steps, then parallelization is possible, for example, the array indices will iterate over 4 threads (so that the indices do not overlap), then the array array will fill up faster - gil9red
  • The essence of the task is to fill the array array (form - (x, y, 3)) with white / black tuples based on the img array (contains true / false, form - (x, y)). - vldmr

1 answer 1

Try this:

 array[np.nonzero(img)] = white 

or even more beautiful and faster ( as @jfs advised ):

 arr[img != 0] = white 

instead of the whole cycle

Demo:

 In [169]: %paste arr = np.arange(27).reshape(3,3,3) img = np.array([[0,1,0], [0,0,0], [0,0,1]]) expected = arr.copy() for i in range(img.shape[0]): for j in range(img.shape[1]): if img[i, j]: expected[i, j, :] = 100 ## -- End pasted text -- 

Original array:

 In [170]: arr Out[170]: array([[[ 0, 1, 2], [ 3, 4, 5], [ 6, 7, 8]], [[ 9, 10, 11], [12, 13, 14], [15, 16, 17]], [[18, 19, 20], [21, 22, 23], [24, 25, 26]]]) 

Expected array:

 In [171]: expected Out[171]: array([[[ 0, 1, 2], [100, 100, 100], [ 6, 7, 8]], [[ 9, 10, 11], [ 12, 13, 14], [ 15, 16, 17]], [[ 18, 19, 20], [ 21, 22, 23], [100, 100, 100]]]) In [172]: arr == expected Out[172]: array([[[ True, True, True], [False, False, False], [ True, True, True]], [[ True, True, True], [ True, True, True], [ True, True, True]], [[ True, True, True], [ True, True, True], [False, False, False]]], dtype=bool) 

using numpy indexing:

 In [173]: arr[np.nonzero(img)] = 100 

Check:

 In [174]: (arr == expected).all() Out[174]: True 

Performance comparison:

 In [1]: %paste arr = np.random.randint(0,255,(10**4,10**4,3)) img = np.random.choice([True, False], (arr.shape[0], arr.shape[1])) ## -- End pasted text -- In [5]: arr.shape Out[5]: (10000, 10000, 3) In [6]: img.shape Out[6]: (10000, 10000) In [7]: %timeit arr[np.nonzero(img)] 1 loop, best of 3: 6.28 s per loop In [8]: %timeit arr[img != 0, :] 1 loop, best of 3: 5.5 s per loop 
  • 2
    You can explicitly compare with zero: arr[img != 0] = 100 (to show how to add other conditions ). To find out if arrays np.all(arr==expected) or np.allclose(arr, expected) are equal for float values. - jfs
  • @jfs, thanks !! it looks better and simpler, but I'm not sure that there will be a small loss in performance - you need to test it on large arrays - MaxU
  • @jfs, compared the performance for arrays of a dimension (10,000, 10,000, 3) - your version looks faster and clearer! - MaxU