def rebin(image, rebinned_shape, factor):
    """

    Parameters
    ----------
    image : 2D np.array
        the larger PSF grid
    rebinned_shape : iterable with size 2
        shape of the image after rebinning
    factor : int
        smoothing factor

    Returns
    -------
    2D np.array
        the rebinned image with shape `rebinned_shape`

    """
    x_dim, y_dim = rebinned_shape # shape after coarse binning
    x_kernel_dim, y_kernel_dim = image.shape[0]//x_dim, image.shape[1]//y_dim # shape of each kernel, the pixels inside of which will be averaged (should be equal to [factor, factor])
    new_shape = x_dim, x_kernel_dim, y_dim, y_kernel_dim
    rebinned_image = image.reshape(new_shape).mean(axis=-1).mean(axis=1)*factor**2 # average across the dimensions of each kernel
    return rebinned_image