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:
- 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]]
- 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
How to Use Python to Execute a Curl Command
How to Get the Nth Element of a Python List or a Default If Not Available
Pycharm Current Working Directory
Pyqt4 Wait in Thread for User Input from Gui
How to Change Plot Background Color
Pip Issue Installing Almost Any Library
Is There a Generator Version of 'String.Split()' in Python
Handle Flask Requests Concurrently with Threaded=True
How to Change the Python Version in Visual Studio Code
Best Way to Format Integer as String with Leading Zeros
Reference List Item by Index Within Django Template
Django Reverse Lookup of Foreign Keys
What Does the Term "Broadcasting" Mean in Pandas Documentation
How to Set a Default Parameter Equal to Another Parameter Value