python how to pad numpy array with zeros

I want to know how I can pad a 2D numpy array with zeros using python 2.6.6 with numpy version 1.5.0. Sorry! But these are my limitations. Therefore I cannot use np.pad. For example, I want to pad a with zeros such that its shape matches b. The reason why I want to do this is so I can do:

    b-a

such that

    >>> a
    array([[ 1.,  1.,  1.,  1.,  1.],
           [ 1.,  1.,  1.,  1.,  1.],
           [ 1.,  1.,  1.,  1.,  1.]])
    >>> b
    array([[ 3.,  3.,  3.,  3.,  3.,  3.],
           [ 3.,  3.,  3.,  3.,  3.,  3.],
           [ 3.,  3.,  3.,  3.,  3.,  3.],
           [ 3.,  3.,  3.,  3.,  3.,  3.]])
    >>> c
    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]])

The only way I can think of doing this is appending, however this seems pretty ugly. is there a cleaner solution possibly using b.shape?

Edit, Thank you to MSeiferts answer. I had to clean it up a bit, and this is what I got:

    def pad(array, reference_shape, offsets):
        """
        array: Array to be padded
        reference_shape: tuple of size of ndarray to create
        offsets: list of offsets (number of elements must be equal to the dimension of the array)
        will throw a ValueError if offsets is too big and the reference_shape cannot handle the offsets
        """

        # 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(offsets[dim], offsets[dim] + array.shape[dim]) for dim in range(array.ndim)]
        # Insert the array in the result at the specified offsets
        result[insertHere] = array
        return result

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)

From: stackoverflow.com/q/35751306