34

I think that my issue should be really simple, yet I can not find any help on the Internet whatsoever. I am very new to Python, so it is possible that I am missing something very obvious.

I have an array, S, like this [x x x] (one-dimensional). I now create a diagonal matrix, sigma, with np.diag(S) - so far, so good. Now, I want to resize this new diagonal array so that I can multiply it by another array that I have.

import numpy as np
...
shape = np.shape((6, 6)) #This will be some pre-determined size
sigma = np.diag(S) #diagonalise the matrix - this works
my_sigma = sigma.resize(shape) #Resize the matrix and fill with zeros - returns "None" - why?

However, when I print the contents of my_sigma, I get "None". Can someone please point me in the right direction, because I can not imagine that this should be so complicated.

Thanks in advance for any help!

Casper

Graphical:

I have this:

[x x x]

I want this:

[x 0 0]
[0 x 0]
[0 0 x]
[0 0 0]
[0 0 0]
[0 0 0] - or some similar size, but the diagonal elements are important.
5
  • Are you defining shape(), diag() and resize(), or are those from a library you are using? Commented Feb 12, 2012 at 18:57
  • resize() is from the numpy library, I should have specified that. Commented Feb 12, 2012 at 18:59
  • This is numpy, right? If I'm understanding correctly, sigma has data in it, but you're wanting to make sigma larger and zero-fill the new elements. Is that correct? If you just need a new zero-filled array, use numpy.zeros((6,6)) Commented Feb 12, 2012 at 19:01
  • 1
    np.shape((6, 6)) returns the shape of (6,6) which is (2,) probably not the (6,6) you wanted. reshaping the diag matrix doesn't make sense to me. you will have mostly zero's in it....not sure what you really want here Commented Feb 12, 2012 at 19:11
  • I need to use sigma with its current data, but I also need to resize it so that I can multiply it with another matrix. Therefore, I just need to get sigma to the appropriate size, filling the remaining values with zeros is exactly what I want. I am doing a Singular Value Decomposition, and sigma is my S matrix that has to be diagonalised and multiplied with my MxM S matrix. Commented Feb 12, 2012 at 19:31

5 Answers 5

62

There is a new numpy function in version 1.7.0 numpy.pad that can do this in one-line. Like the other answers, you can construct the diagonal matrix with np.diag before the padding. The tuple ((0,N),(0,0)) used in this answer indicates the "side" of the matrix which to pad.

import numpy as np

A = np.array([1, 2, 3])

N = A.size
B = np.pad(np.diag(A), ((0,N),(0,0)), mode='constant')

B is now equal to:

[[1 0 0]
 [0 2 0]
 [0 0 3]
 [0 0 0]
 [0 0 0]
 [0 0 0]]
Sign up to request clarification or add additional context in comments.

1 Comment

Thanks for posting an update answer. Before my +1 our answers were tied but mine was pre numpy 1.7. Not sure you will ever get to top answer because StackOverflow has a "first answer wins" bias. Nice to see new info...
25

sigma.resize() returns None because it operates in-place. np.resize(sigma, shape), on the other hand, returns the result but instead of padding with zeros, it pads with repeats of the array.

Also, the shape() function returns the shape of the input. If you just want to predefine a shape, just use a tuple.

import numpy as np
...
shape = (6, 6) #This will be some pre-determined size
sigma = np.diag(S) #diagonalise the matrix - this works
sigma.resize(shape) #Resize the matrix and fill with zeros

However, this will first flatten out your original array, and then reconstruct it into the given shape, destroying the original ordering. If you just want to "pad" with zeros, instead of using resize() you can just directly index into a generated zero-matrix.

# This assumes that you have a 2-dimensional array
zeros = np.zeros(shape, dtype=np.int32)
zeros[:sigma.shape[0], :sigma.shape[1]] = sigma

2 Comments

Thanks, this is very close to what I need- but now my new matrix loses its diagonality, i.e. the elements that were originally along the diagonal don't stay there. Any idea how to fix this?
Thanks! This is perfect, thanks for all your effort, voithos!
5

I see the edit... you do have to create the zeros first and then move some numbers into it. np.diag_indices_from might be useful for you

bigger_sigma = np.zeros(shape, dtype=sigma.dtype)
diag_ij = np.diag_indices_from(sigma)
bigger_sigma[diag_ij] = sigma[diag_ij] 

3 Comments

This seems to work as well, thanks! I'm glad to see that it is quite a tricky process and that I wasn't just missing something.
I like this better. More readable and only adds whatever is needed. Also, using sigma.dtype is a good idea.
I'm guessing the context of the question is that of an SVD of a rectangular matrix (with full_matrices=True), and making the reconstruction A = USV'. In that case, I would prefer this type of solution.
3

This solution works with resize function

Take a sample array

S= np.ones((3))
print (S)
# [ 1.  1.  1.]
d= np.diag(S) 
print(d)
"""
[[ 1.  0.  0.]
 [ 0.  1.  0.]
 [ 0.  0.  1.]]

"""

This dosent work, it just add a repeating values

np.resize(d,(6,3))
"""
adds a repeating value
array([[ 1.,  0.,  0.],
       [ 0.,  1.,  0.],
       [ 0.,  0.,  1.],
       [ 1.,  0.,  0.],
       [ 0.,  1.,  0.],
       [ 0.,  0.,  1.]])
"""

This does work

d.resize((6,3),refcheck=False)
print(d)
"""
[[ 1.  0.  0.]
 [ 0.  1.  0.]
 [ 0.  0.  1.]
 [ 0.  0.  0.]
 [ 0.  0.  0.]
 [ 0.  0.  0.]]
"""

1 Comment

If you change the second dimension and not the first one, it will not
0

Another pure python solution is

a = [1, 2, 3]
b = []
for i in range(6):
    b.append((([0] * i) + a[i:i+1] + ([0] * (len(a) - 1 - i)))[:len(a)])

b is now

[[1, 0, 0], [0, 2, 0], [0, 0, 3], [0, 0, 0], [0, 0, 0], [0, 0, 0]]

it's a hideous solution, I'll admit that. However, it illustrates some functions of the list type that can be used.

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.