Create all lags of given columns
Well you've written you don't like it, but why?  Is this ever used with relevantly large input?  If so, you might have to consider allocating the right size of data frame from the start and assign the values afterwards.

If not, I can only see some small things that could be a little bit more succinct, and perhaps np.ones_like(df) instead of with df.loc[:,:] ... but otherwise this seems fine?

Like the following removes a bit of duplicated code, but is not inherently better:

def suffixed_columns(df, suffix):
    return ["{}{}".format(column, suffix) for column in df.columns]

def constants(df):
    return pd.DataFrame(np.ones_like(df), index=df.index, columns=suffixed_columns(df, "_Int"))

def lag(df, n):
    new_df = df.shift(n)
    new_df.columns = suffixed_columns(df, "_Lag{:02d}".format(n))
    return new_df

def lagged_dataframe(df, lags=1):
    return pd.concat([df, constants(df)] + [lag(df, i) for i in range(1, lags + 1)], axis=1)