0

What's the most efficient way to pad an array of matrices with zeros?

example:

# Lets construct an array of 2 matrices from 3 arrays of vectors
import numpy as np

A = np.array([[0,1,2],[3,4,5]])       # 2 vectors
B = np.array([[6,7,8],[9,10,11]])     # 2 vectors
C = np.array([[12,13,14],[15,16,17]]) # 2 vectors
M = np.dstack((A,B,C))
'''
# Result: array([[[ 0,  6, 12],
                  [ 1,  7, 13],
                  [ 2,  8, 14]],

                 [[ 3,  9, 15],
                  [ 4, 10, 16],
                  [ 5, 11, 17]]]) #
'''

I want to add a column and/or a row of zeros to every matrix element in the array such as:

'''
# Result: array([[[ 0,  6, 12, 0],
              [ 1,  7, 13, 0],
              [ 2,  8, 14, 0],
              [ 0,  0,  0, 0]],

             [[ 3,  9, 15, 0],
              [ 4, 10, 16, 0],
              [ 5, 11, 17, 0]
              [ 0,  0,  0, 0]]]) #
'''

2 Answers 2

2

np.pad will work, but for this case it is overkill. We can do it directly with:

A sample 3d array (different dimensions make changes more obvious)

In [408]: M=np.arange(2*3*4).reshape((2,3,4))    
In [409]: M
Out[409]: 
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]]])

A blank array of the desired target shape

In [410]: M1=np.zeros((2,4,5),M.dtype)

Copy values from M to the target in the right slice range.

In [411]: M1[:,:-1,:-1]=M
In [412]: M1
Out[412]: 
array([[[ 0,  1,  2,  3,  0],
        [ 4,  5,  6,  7,  0],
        [ 8,  9, 10, 11,  0],
        [ 0,  0,  0,  0,  0]],

       [[12, 13, 14, 15,  0],
        [16, 17, 18, 19,  0],
        [20, 21, 22, 23,  0],
        [ 0,  0,  0,  0,  0]]])

A copy like this is required. There's no way of expanding the size of M itself. pad returns a new array as well, having performed a general version of this allocate and copy. So there isn't much of an efficiency issue.

You could also concatenate (or 'append') a 0 row or column in the right dimensions. But what I've illustrated does it in one step.

Sign up to request clarification or add additional context in comments.

1 Comment

nice, this is about 3x faster than np.pad on my use case (over 1 million matrices)
1

You're going to want to use numpy.pad to do this. You can use the second input argument to specify the amount to pad before and after the data in each of the dimensions of the array. Then specify a constant padding type where the padding value is 0 (the default).

result = numpy.pad(M, ((0,0),(0,1),(0,1)), 'constant', constant_values=0)
array([[[ 0,  6, 12,  0],
        [ 1,  7, 13,  0],
        [ 2,  8, 14,  0],
        [ 0,  0,  0,  0]],

       [[ 3,  9, 15,  0],
        [ 4, 10, 16,  0],
        [ 5, 11, 17,  0],
        [ 0,  0,  0,  0]]])

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.