I created an array with a diagonal edge by using two for loops, but I wonder if there is a simpler way to do so, for example with a list comprehension:
im_diag = np.zeros((im_size, im_size), dtype=np.int8)
for x in range(im_size):
for y in range(im_size):
if x+y >= im_size:
im_diag[x,y] = 1
Output (im_size = 5):
>>> im_size
array([[0, 0, 0, 0, 0],
[0, 0, 0, 0, 1],
[0, 0, 0, 1, 1],
[0, 0, 1, 1, 1],
[0, 1, 1, 1, 1]], dtype=int8)
In general when using numpy, it's far better to use a vectorised method, which will become a lot faster than methods using loops and list-comprehensions as the size of the desired array increases.
>>> np.flip(np.tril(np.ones((5,5)), k=-1), 1)
array([[0., 0., 0., 0., 0.],
[0., 0., 0., 0., 1.],
[0., 0., 0., 1., 1.],
[0., 0., 1., 1., 1.],
[0., 1., 1., 1., 1.]])
np.ones to create an array of 1s,
np.tril to create a lower triangular array
np.flip to horizontally flip the array
Time Comparison with other answers:

As shown, with n>=10, the numpy method is faster, and as n gets larger, this method will tend to be about 10 times faster than list comprehension solutions.
Code to reproduce:
import perfplot
import numpy as np
def cdjb(n):
return np.flip(np.tril(np.ones((n,n)), k=-1), 1)
def displayname(n):
return [[int(j > i) for j in range(n)] for i in range(n)][::-1]
def MikeMajara(n):
return [[1 if i+j >= n else 0 for i in range(n)] for j in range(n)]
perfplot.show(
setup=lambda n: n,
n_range=[2**k for k in range(14)],
kernels=[
cdjb,displayname,MikeMajara
],
xlabel='Size of Array',
)
With list comprehension (no numpy required):
n = 5
[[int(j > i) for j in range(n)] for i in range(n)][::-1]
Gives
[[0, 0, 0, 0, 0],
[0, 0, 0, 0, 1],
[0, 0, 0, 1, 1],
[0, 0, 1, 1, 1],
[0, 1, 1, 1, 1]]
where [::-1] just reverses the outer list.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With