Python How to Pad Numpy Array with Zeros

Zero pad numpy array

For your use case you can use resize() method:

A = np.array([1,2,3,4,5])
A.resize(8)

This resizes A in place. If there are refs to A numpy throws a vale error because the referenced value would be updated too. To allow this add refcheck=False option.

The documentation states that missing values will be 0:

Enlarging an array: as above, but missing entries are filled with zeros

python how to pad numpy array with zeros

Very simple, you create an array containing zeros using the reference shape:

result = np.zeros(b.shape)
# actually you can also use result = np.zeros_like(b)
# but that also copies the dtype not only the shape

and then insert the array where you need it:

result[:a.shape[0],:a.shape[1]] = a

and voila you have padded it:

print(result)
array([[ 1., 1., 1., 1., 1., 0.],
[ 1., 1., 1., 1., 1., 0.],
[ 1., 1., 1., 1., 1., 0.],
[ 0., 0., 0., 0., 0., 0.]])

You can also make it a bit more general if you define where your upper left element should be inserted

result = np.zeros_like(b)
x_offset = 1 # 0 would be what you wanted
y_offset = 1 # 0 in your case
result[x_offset:a.shape[0]+x_offset,y_offset:a.shape[1]+y_offset] = a
result

array([[ 0., 0., 0., 0., 0., 0.],
[ 0., 1., 1., 1., 1., 1.],
[ 0., 1., 1., 1., 1., 1.],
[ 0., 1., 1., 1., 1., 1.]])

but then be careful that you don't have offsets bigger than allowed. For x_offset = 2 for example this will fail.


If you have an arbitary number of dimensions you can define a list of slices to insert the original array. I've found it interesting to play around a bit and created a padding function that can pad (with offset) an arbitary shaped array as long as the array and reference have the same number of dimensions and the offsets are not too big.

def pad(array, reference, offsets):
"""
array: Array to be padded
reference: Reference array with the desired shape
offsets: list of offsets (number of elements must be equal to the dimension of the array)
"""
# Create an array of zeros with the reference shape
result = np.zeros(reference.shape)
# Create a list of slices from offset to offset + shape in each dimension
insertHere = [slice(offset[dim], offset[dim] + array.shape[dim]) for dim in range(a.ndim)]
# Insert the array in the result at the specified offsets
result[insertHere] = a
return result

And some test cases:

import numpy as np

# 1 Dimension
a = np.ones(2)
b = np.ones(5)
offset = [3]
pad(a, b, offset)

# 3 Dimensions

a = np.ones((3,3,3))
b = np.ones((5,4,3))
offset = [1,0,0]
pad(a, b, offset)

padding 2D numpy array with 0s

It's also possible to pad a 2D numpy arrays by passing a tuple of tuples as padding width, which takes the format of ((top, bottom), (left, right))

example:

import numpy as np
A=np.array([[1, 2, 3, 4], [5, 6, 7, 8]])
print(A.shape)

Output:

(2, 4)

If I want to make one array shape((5, 9) :

B = np.pad(A, (((5-2),0),(7-2,0)), 'constant')
C = np.pad(A, (((5-3),1),(7-4,2)), 'constant')
print(B.shape) #--->shape((5, 9)
print(C.shape) #--->shape((5, 9)

then:

#((top, bottom), (left, right)):
#(144,X) -->(208,5000)
#B = np.pad(A, (((208-144),0),(5000-X,0)), 'constant'): One of the possible modes

How can I right pad a numpy array with zeroes?

Here is a generic approach using np.pad. The trick is to get the pad_width argument right. In your original question, the correct pad_width would be [(0, 0), (0, 21), (0, 0)]. Each pair of numbers is the padding before the axis and then after the axis. You want to right pad the second dimension, so the pair should be (0, 21). The methods below calculate the correct pad width argument based on shape of the original array and the desired array shape.

import numpy as np

orig_shape = (1, 79, 161)
new_shape = (1, 100, 161)

pad_width = [(0, j - i) for i, j in zip(orig_shape, new_shape)]
# pad_width = [(0, 0), (0, 21), (0, 0)]
orig_array = np.random.rand(*orig_shape)
padded = np.pad(orig_array, pad_width)

Another option: you can create a new numpy array of zeros, and then fill it in with your existing values.

import numpy as np
x = np.zeros((1, 100, 161))
x[:, :79, :] = OLD_ARRAY

Padding NumPy arrays to a specific size

Here:

import numpy as np

arr = np.random.randint(0, 10, (7, 4))

def padding(array, xx, yy):
"""
:param array: numpy array
:param xx: desired height
:param yy: desirex width
:return: padded array
"""

h = array.shape[0]
w = array.shape[1]

a = (xx - h) // 2
aa = xx - a - h

b = (yy - w) // 2
bb = yy - b - w

return np.pad(array, pad_width=((a, aa), (b, bb)), mode='constant')

print(padding(arr, 99, 13).shape) # just proving that it outputs the right shape
Out[83]: (99, 13)

An example:

padding(arr, 7, 11) # originally 7x4
Out[85]: 
array([[0, 0, 0, 4, 8, 8, 8, 0, 0, 0, 0],
[0, 0, 0, 5, 9, 6, 3, 0, 0, 0, 0],
[0, 0, 0, 4, 7, 6, 1, 0, 0, 0, 0],
[0, 0, 0, 5, 6, 5, 7, 0, 0, 0, 0],
[0, 0, 0, 6, 6, 3, 3, 0, 0, 0, 0],
[0, 0, 0, 6, 0, 9, 6, 0, 0, 0, 0],
[0, 0, 0, 9, 4, 4, 0, 0, 0, 0, 0]])

Numpy pad zeroes of given size

You could re-write your function like this:

import numpy as np

def pad_array(l, item_size, pad_size=5):

if pad_size < len(l):
return np.array(l)

s = len(l)
res = np.zeros((pad_size, item_size)) # create an array of (item_size, pad_size)
res[:s] = l # set the first rows equal to the elements of l

return res

B = [np.array([0, 1]), np.array([1, 0]), np.array([1, 1])]
AB = pad_array(B, 2)

print(AB)

Output

[[0. 1.]
[1. 0.]
[1. 1.]
[0. 0.]
[0. 0.]]

The idea is to create an array of zeroes and then fill the first rows with the values from the input list.

How to pad an array non-symmetrically (e.g., only from one side)?

It turns our that with a simple change we can achieve that:

def pad_with(vector, pad_width, iaxis, kwargs):
pad_value = kwargs.get('padder', 0)
vector[:pad_width[0]] = pad_value
if pad_width[1] != 0: # <-- the only change (0 indicates no padding)
vector[-pad_width[1]:] = pad_value

Here are some examples:

  1. Padding 1 row of zeros (only) to the top:
>>> np.pad(a, ((1, 0), (0, 0)), pad_with, padder=0)
[[0 0 0]
[1 1 1]
[1 1 1]]

  1. Padding 2 rows of zeros, both to the left and right:
np.pad(a, ((0, 0), (2, 2)), pad_with, padder=0)
[[0 0 1 1 1 0 0]
[0 0 1 1 1 0 0]]

and so on.

How can I pad matrix in python without using the np.pad() function?

You could create a custom pad function like so:

Very late edit: Do not use this function, use the one below it called pad2().

def pad(mat, padding):

dim1 = len(mat)
dim2 = len(mat[0])

# new empty matrix of the required size
new_mat = [
[0 for i in range(dim1 + padding*2)]
for j in range(dim2 + padding*2)
]

# "insert" original matix in the empty matrix
for i in range(dim1):
for j in range(dim2):
new_mat[i+padding][j+padding] = mat[i][j]

return new_mat

It might not be the optimal/fastest solution, but this should work fine for regular sized matrices.


Very late edit:
I tried to use this function on a non square matrix and noticed it threw an IndexError. So for future reference here is the corrected version that works for N x M matrices (where N != M):

def pad2(mat, padding, pad_with=0):
n_rows = len(mat)
n_cols = len(mat[0])

# new empty matrix of the required size
new_mat = [
[pad_with for col in range(n_cols + padding * 2)]
for row in range(n_rows + padding * 2)
]

# "insert" original matix in the empty matrix
for row in range(n_rows):
for col in range(n_cols):
new_mat[row + padding][col + padding] = mat[row][col]

return new_mat

Adding a numpy array to another which has different dimensions

If you just want to concatinate arrays:

a = np.ones((1200,1000))
b = np.ones((1200, 500))
c = np.concatenate((a, b), axis=1)
c.shape # == (1200, 1500)

If you want elementwise addition, then reshape b to have the same dimentions as a

a = np.ones((1200,1000))
b = np.ones((1200, 500))
b_pad = np.zeros(a.shape)
b_pad[:b.shape[0],:b.shape[1]] = b
a + b_pad
array([[2., 2., 2., ..., 1., 1., 1.],
[2., 2., 2., ..., 1., 1., 1.],
[2., 2., 2., ..., 1., 1., 1.],
...,
[2., 2., 2., ..., 1., 1., 1.],
[2., 2., 2., ..., 1., 1., 1.],
[2., 2., 2., ..., 1., 1., 1.]])

If you want a reusable function for this, then have a look at this question

  • python how to pad numpy array with zeros


Related Topics



Leave a reply



Submit