Reputation: 292
I had wrote a function to generate a example numpy array by for loop. But it is too slow for larger dimension.
import numpy as np
mat = np.zeros((5, 5))
def func(im):
im = im.copy()
h,w = im.shape
for i in range(h):
for j in range(w):
if (i + j) % 2 == 0:
im[i, j] = 255
return im
print(func(mat))
# array([[ 255., 0., 255., ..., 255., 0., 255.],
# [ 0., 255., 0., ..., 0., 255., 0.],
# [ 255., 0., 255., ..., 255., 0., 255.],
# ...,
# [ 255., 0., 255., ..., 255., 0., 255.],
# [ 0., 255., 0., ..., 0., 255., 0.],
# [ 255., 0., 255., ..., 255., 0., 255.]])
Upvotes: 1
Views: 1789
Reputation: 221674
We will start with a zero intialized array. So, that will be : np.zeros((heigh, width))
. Next up, we would have few approaches to fill it with such a pattern of alternating 255s
.
Approach #1 : Use open range arrays with np.ogrid
to simulate those iterators and directly translate the comparisons in a vectorized manner leveraging broadcasting
-
I,J = np.ogrid[:h,:w]
im[(I+J)%2==0] = 255
Approach #2 : Taking a closer look, it seem you are setting every other element in each row to 255
, starting from the first element for first row and second element for the second row and back to first for the third row and so on. Thus, we can use slicing
as well and should be pretty efficient -
im[::2,::2] = 255
im[1::2,1::2] = 255
Runtime test
Approaches -
def func(im):
h,w = im.shape
for i in range(h):
for j in range(w):
if (i + j) % 2 == 0:
im[i, j] = 255
return im
def app1(im):
h,w = im.shape
I,J = np.ogrid[:h,:w]
im[(I+J)%2==0] = 255
return im
def app2(im):
im[::2,::2] = 255
im[1::2,1::2] = 255
return im
Verify -
In [74]: im = np.random.randint(0,255,(1000,1000))
In [75]: im1 = im.copy()
...: im2 = im.copy()
...: im3 = im.copy()
...:
In [76]: func(im1)
...: app1(im2)
...: app2(im3)
...:
Out[76]:
array([[255, 133, 255, ..., 14, 255, 41],
[235, 255, 191, ..., 255, 40, 255],
[255, 151, 255, ..., 51, 255, 18],
...,
[ 50, 255, 177, ..., 255, 193, 255],
[255, 245, 255, ..., 114, 255, 27],
[223, 255, 148, ..., 255, 200, 255]])
In [77]: print np.allclose(im1,im2)
...: print np.allclose(im1,im3)
...:
True
True
Timings -
In [78]: %timeit func(im)
10 loops, best of 3: 106 ms per loop
In [79]: %timeit app1(im)
100 loops, best of 3: 14 ms per loop
In [80]: %timeit app2(im)
1000 loops, best of 3: 415 µs per loop
In [82]: 106/0.415 # Speedup with approach #2 over original one
Out[82]: 255.42168674698797
Upvotes: 4
Reputation: 831
You can use the fancy indexing properties of numpy arrays.
An example that does exactly what you need is:
import numpy as np
arr = np.zeros((10, 10))
a = np.arange(0, 10, 2)
b = np.arange(1, 10, 2)
arr[a[:, None], a[None, :]] = 255
arr[b[:, None], b[None, :]] = 255
print(arr)
array([[ 255., 0., 255., ..., 0., 255., 0.],
[ 0., 255., 0., ..., 255., 0., 255.],
[ 255., 0., 255., ..., 0., 255., 0.],
...,
[ 0., 255., 0., ..., 255., 0., 255.],
[ 255., 0., 255., ..., 0., 255., 0.],
[ 0., 255., 0., ..., 255., 0., 255.]])
Upvotes: 2