title: Make Multiple Shifted (Lagged) Columns in Pandas
body: <p>I have a time-series DataFrame and I want to replicate each of my 200 features/columns as additional lagged features. So at the moment I have features at time t and want to create features at timestep t-1, t-2 and so on. </p>
  
  <p>I know this is best done with df.shift() but I'm having trouble putting it altogether. I want to also rename the columns to 'feature (t-1)', 'feature (t-2)'.</p>
  
  <p>My pseudo-code attempt would be something like:</p>
  
  <pre><code>lagged_values = [1,2,3,10]
  for every lagged_values
      for every column, make a new feature column with df.shift(lagged_values)
      make new column have name 'original col name'+'(t-(lagged_values))'
  </code></pre>
  
  <p>In the end if I have 200 columns and 4 lagged timesteps I would have a new df with 1,000 features (200 each at t, t-1, t-2, t-3 and t-10).</p>
  
  <p>I have found something similar but it doesn't keep the original column names (renames to var1, var2, etc) as per <a href="https://machinelearningmastery.com/convert-time-series-supervised-learning-problem-python/" rel="noreferrer">machine learning mastery</a>. Unfortunately I don't understand it well enough to modify it to my problem.</p>
  
  <pre><code>def series_to_supervised(data, n_in=1, n_out=1, dropnan=True):
      """
      Frame a time series as a supervised learning dataset.
      Arguments:
          data: Sequence of observations as a list or NumPy array.
          n_in: Number of lag observations as input (X).
          n_out: Number of observations as output (y).
          dropnan: Boolean whether or not to drop rows with NaN values.
      Returns:
          Pandas DataFrame of series framed for supervised learning.
      """
      n_vars = 1 if type(data) is list else data.shape[1]
      df = DataFrame(data)
      cols, names = list(), list()
      # input sequence (t-n, ... t-1)
      for i in range(n_in, 0, -1):
          cols.append(df.shift(i))
          names += [('var%d(t-%d)' % (j+1, i)) for j in range(n_vars)]
      # forecast sequence (t, t+1, ... t+n)
      for i in range(0, n_out):
          cols.append(df.shift(-i))
          if i == 0:
              names += [('var%d(t)' % (j+1)) for j in range(n_vars)]
          else:
              names += [('var%d(t+%d)' % (j+1, i)) for j in range(n_vars)]
      # put it all together
      agg = concat(cols, axis=1)
      agg.columns = names
      # drop rows with NaN values
      if dropnan:
          agg.dropna(inplace=True)
      return agg
  </code></pre>