0

IN the scipy lecture notes for indexing

There is an example problem, to create this array.

[[0., 0., 0., 0., 0.],
 [2., 0., 0., 0., 0.],
 [0., 3., 0., 0., 0.],
 [0., 0., 4., 0., 0.],
 [0., 0., 0., 5., 0.],
 [0., 0., 0., 0., 6.]]

The problem for me is getting the extra blank row at the top. How do I acheive the example?

This is my current code.

d =np.zeros([5,],dtype=int) + np.diag(arange(2,7,1))

d
Out[66]: 
array([[2, 0, 0, 0, 0],
       [0, 3, 0, 0, 0],
       [0, 0, 4, 0, 0],
       [0, 0, 0, 5, 0],
       [0, 0, 0, 0, 6]])
0

5 Answers 5

4

You can do this with diag and indexing alone using the k argument to diag:

np.diag(np.arange(2,7), k = -1)

gives:

array([[0, 0, 0, 0, 0, 0],
       [2, 0, 0, 0, 0, 0],
       [0, 3, 0, 0, 0, 0],
       [0, 0, 4, 0, 0, 0],
       [0, 0, 0, 5, 0, 0],
       [0, 0, 0, 0, 6, 0]])

That's almost right. You just need to lose the last column which you can do with an slice:

np.diag(np.arange(2,7), k = -1)[:, :-1]

which gives the desired result:

array([[0, 0, 0, 0, 0],
       [2, 0, 0, 0, 0],
       [0, 3, 0, 0, 0],
       [0, 0, 4, 0, 0],
       [0, 0, 0, 5, 0],
       [0, 0, 0, 0, 6]])
Sign up to request clarification or add additional context in comments.

1 Comment

Or make it too large on the other end: np.diag(np.arange(1,7))[:,1:]
2

Use np.append:

>>> zero_row = np.zeros((1,5))
>>> matrix   = np.diag(np.arange(2,7,1))
>>> np.append(zero_row, matrix, axis=0)
<<< array([[0., 0., 0., 0., 0.],
           [2., 0., 0., 0., 0.],
           [0., 3., 0., 0., 0.],
           [0., 0., 4., 0., 0.],
           [0., 0., 0., 5., 0.],
           [0., 0., 0., 0., 6.]])

Comments

2

Here's a way of generating the array without diag. Instead I index a diagonal set of elements in a zeros array:

In [167]: x = np.zeros((6,5))                                                     
In [168]: x[np.arange(1,6), np.arange(5)] = np.arange(2,7)                        
In [169]: x                                                                     
Out[169]: 
array([[0., 0., 0., 0., 0.],
       [2., 0., 0., 0., 0.],
       [0., 3., 0., 0., 0.],
       [0., 0., 4., 0., 0.],
       [0., 0., 0., 5., 0.],
       [0., 0., 0., 0., 6.]])

Comments

1
import numpy as np

m = np.zeros([5,])
n = np.diag(np.arange(2,7,1))

m = np.vstack((m,n))
print(m)

We can use vstack

Comments

1

You can also use reshape like so:

out = np.zeros((6, 5))                                                              
out.reshape(5, 6)[:, 5] = np.arange(2, 7)                                            
out                                                                                                         
# array([[0., 0., 0., 0., 0.],
#        [2., 0., 0., 0., 0.],
#        [0., 3., 0., 0., 0.],
#        [0., 0., 4., 0., 0.],
#        [0., 0., 0., 5., 0.],
#        [0., 0., 0., 0., 6.]])

or very similarly:

out = np.zeros((6, 5))
out.reshape(-1)[5::6] = np.arange(2, 7)
out
# array([[0., 0., 0., 0., 0.],
#        [2., 0., 0., 0., 0.],
#        [0., 3., 0., 0., 0.],
#        [0., 0., 4., 0., 0.],
#        [0., 0., 0., 5., 0.],
#        [0., 0., 0., 0., 6.]])

Both these methods are faster than everything posted so far:

import numpy as np
from timeit import timeit

def od_hpj():
    out = np.zeros((6, 5))
    out[np.arange(1,6), np.arange(5)] = np.arange(2,7)                        
    return out

def od_mm():
    return np.diag(np.arange(2,7), k = -1)[:, :-1]

def od_ks():
    m = np.zeros([5,])
    n = np.diag(np.arange(2,7,1))
    return np.vstack((m,n))

def od_as():
    zero_row = np.zeros((1,5))
    matrix   = np.diag(np.arange(2,7,1))
    return np.append(zero_row, matrix, axis=0)

def od_pp1():
    out = np.zeros((6, 5))
    out.reshape(5, 6)[:, 5] = np.arange(2, 7)
    return out

def od_pp2():
    out = np.zeros((6, 5))
    out.reshape(-1)[5::6] = np.arange(2, 7)
    return out

for n, o in list(globals().items()):
    if n.startswith("od_"):
        print(f"{n.replace('od_', ''):3s}: {timeit(o):.3f} us")

Sample run:

hpj: 3.379 us
mm : 2.952 us
ks : 7.804 us
as : 5.222 us
pp1: 1.735 us
pp2: 2.418 us

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.