Here's one fairly efficient way to do it that will work with non-square matrices:
DIRS = NONE, UP, DOWN, LEFT, RIGHT = 'unshifted', 'up', 'down', 'left', 'right'
def shift(matrix, direction, dist):
    """ Shift a 2D matrix in-place the given distance of rows or columns in the
        specified (NONE, UP, DOWN, LEFT, RIGHT) direction and return it.
    """
    if dist and direction in (UP, DOWN, LEFT, RIGHT):
        n = 0
        if direction in (UP, DOWN):
            n = (dist % len(matrix) if direction == UP else -(dist % len(matrix)))
        elif direction in (LEFT, RIGHT):
            n = (dist % len(matrix[0]) if direction == LEFT else -(dist % len(matrix[0])))
            matrix[:] = list(zip(*matrix))  # Transpose rows and columns for shifting.
        h = matrix[:n]
        del matrix[:n]
        matrix.extend(h)
        if direction in (LEFT, RIGHT):
            matrix[:] = map(list, zip(*matrix))  # Undo previous transposition.
    return matrix
if __name__ == '__main__':
    # Some non-square test matrices.
    matrix1 = [[1, 2, 3],
               [4, 5, 6],
               [7, 8, 9],
               [10, 11, 12]]
    matrix2 = [[1, 2, 3, 4],
               [5, 6, 7, 8],
               [9, 10, 11, 12]]
    def shift_and_print(matrix, direction, dist):
        GAP =  2  # Plus one for a ":" character.
        indent = max(map(len, DIRS)) + GAP
        print(direction
                + ': ' + (indent-2-len(direction))*' '
                + ('\n'+indent*' ').join(map(str, shift(matrix, direction, dist)))
                + '\n')
    for matrix in matrix1, matrix2:
        for direction in DIRS:
            shift_and_print(matrix, direction, 1)  # Printed results are cumulative.
Output (note that the results are cumulative since the operations are performed in-place and the shifting is applied to the result of the previous call):
no shift: [1, 2, 3]
          [4, 5, 6]
          [7, 8, 9]
          [10, 11, 12]
up:       [4, 5, 6]
          [7, 8, 9]
          [10, 11, 12]
          [1, 2, 3]
down:     [1, 2, 3]
          [4, 5, 6]
          [7, 8, 9]
          [10, 11, 12]
left:     [2, 3, 1]
          [5, 6, 4]
          [8, 9, 7]
          [11, 12, 10]
right:    [1, 2, 3]
          [4, 5, 6]
          [7, 8, 9]
          [10, 11, 12]
no shift: [1, 2, 3, 4]
          [5, 6, 7, 8]
          [9, 10, 11, 12]
up:       [5, 6, 7, 8]
          [9, 10, 11, 12]
          [1, 2, 3, 4]
down:     [1, 2, 3, 4]
          [5, 6, 7, 8]
          [9, 10, 11, 12]
left:     [2, 3, 4, 1]
          [6, 7, 8, 5]
          [10, 11, 12, 9]
right:    [1, 2, 3, 4]
          [5, 6, 7, 8]
          [9, 10, 11, 12]