title: Vectorize operation in Pandas
body: <p>I have this operation on a large Pandas DataFrame, and of course, is extremely slow.</p>
  
  <pre><code>def get_last_status_in_range(df, created_dt, created_id, window_size=15, gap_size=5):
      since = created_dt - timedelta(days=(window_size + gap_size))
      until = created_dt - timedelta(days=gap_size)
      try:
          status = df[(df.created_dt &gt;= since) &amp; (df.created_dt &lt; until) &amp;
                      (df.number_id == created_id)]['status'].iloc[-1]
      except IndexError:
          # Not found
          status = None
      return status
  
  idx = 0
  last_status_in_range = np.array([None] * len(df), dtype=str)
  for row in df.itertuples():
      created_dt = row.created_dt
      created_id = row.number_id
      last_status_in_range[idx] = get_last_status_in_range(df, created_dt, created_id)
      idx += 1
  </code></pre>
  
  <p>My goal is to given a DF with columns "created_dt", "number_id", and "status", obtain for each row the last "status" for the same "number_id" but in a specified range of dates in the past.</p>
  
  <p>By now the only way I find is doing the operation as described above, but for a large DataFrame it is extremely slow, and I couldn't find a vectorise way to do that.</p>
  
  <p>How can I vectorize an operation using some values in the same DataFrame?</p>
  
  <p>EDIT:</p>
  
  <p>Given the following DF:</p>
  
  <pre><code>In [120]: df
  Out[120]: 
     number_id                 created_dt status
  20     BBB 2018-05-18 20:28:51.388001      u
  12     BBB 2018-05-19 12:28:51.388001      u
  2      CCC 2018-05-19 23:28:51.388001      u
  27     CCC 2018-05-20 22:28:51.388001      a
  1      CCC 2018-05-21 05:28:51.388001      u
  14     BBB 2018-05-21 12:28:51.388001      r
  17     AAA 2018-05-24 21:28:51.388001      a
  28     CCC 2018-05-30 16:28:51.388001      a
  0      AAA 2018-05-31 23:28:51.388001      r
  24     CCC 2018-06-01 00:28:51.388001      r
  4      BBB 2018-06-01 11:28:51.388001      r
  23     BBB 2018-06-01 19:28:51.388001      r
  6      AAA 2018-06-03 14:28:51.388001      a
  3      CCC 2018-06-04 15:28:51.388001      u
  19     AAA 2018-06-05 06:28:51.388001      u
  5      AAA 2018-06-05 20:28:51.388001      r
  21     AAA 2018-06-06 04:28:51.388001      a
  9      BBB 2018-06-06 18:28:51.388001      r
  25     AAA 2018-06-07 15:28:51.388001      r
  11     BBB 2018-06-08 09:28:51.388001      r
  10     BBB 2018-06-08 21:28:51.388001      u
  13     BBB 2018-06-09 04:28:51.388001      a
  7      AAA 2018-06-09 16:28:51.388001      r
  22     AAA 2018-06-12 07:28:51.388001      r
  26     BBB 2018-06-13 03:28:51.388001      u
  15     AAA 2018-06-14 08:28:51.388001      a
  8      CCC 2018-06-14 14:28:51.388001      r
  18     CCC 2018-06-15 17:28:51.388001      u
  16     BBB 2018-06-16 02:28:51.388001      a
  29     AAA 2018-06-16 08:28:51.388001      r
  30     AAA 2018-06-17 02:28:51.388001      a
  </code></pre>
  
  <p>I expect that the output would be:</p>
  
  <pre><code>In [124]: df
  Out[124]: 
     number_id                 created_dt status prev_status
  20     BBB 2018-05-18 20:28:51.388001      u        None
  12     BBB 2018-05-19 12:28:51.388001      u        None
  2      CCC 2018-05-19 23:28:51.388001      u        None
  27     CCC 2018-05-20 22:28:51.388001      a        None
  1      CCC 2018-05-21 05:28:51.388001      u        None
  14     BBB 2018-05-21 12:28:51.388001      r        None
  17     AAA 2018-05-24 21:28:51.388001      a        None
  28     CCC 2018-05-30 16:28:51.388001      a           u
  0      AAA 2018-05-31 23:28:51.388001      r           a
  24     CCC 2018-06-01 00:28:51.388001      r           u
  4      BBB 2018-06-01 11:28:51.388001      r           r
  23     BBB 2018-06-01 19:28:51.388001      r           r
  6      AAA 2018-06-03 14:28:51.388001      a           a
  3      CCC 2018-06-04 15:28:51.388001      u           u
  19     AAA 2018-06-05 06:28:51.388001      u           a
  5      AAA 2018-06-05 20:28:51.388001      r           a
  21     AAA 2018-06-06 04:28:51.388001      a           r
  9      BBB 2018-06-06 18:28:51.388001      r           r
  25     AAA 2018-06-07 15:28:51.388001      r           r
  11     BBB 2018-06-08 09:28:51.388001      r           r
  10     BBB 2018-06-08 21:28:51.388001      u           r
  13     BBB 2018-06-09 04:28:51.388001      a           r
  7      AAA 2018-06-09 16:28:51.388001      r           a
  22     AAA 2018-06-12 07:28:51.388001      r           a
  26     BBB 2018-06-13 03:28:51.388001      u           r
  15     AAA 2018-06-14 08:28:51.388001      a           r
  8      CCC 2018-06-14 14:28:51.388001      r           u
  18     CCC 2018-06-15 17:28:51.388001      u           u
  16     BBB 2018-06-16 02:28:51.388001      a           a
  29     AAA 2018-06-16 08:28:51.388001      r           r
  30     AAA 2018-06-17 02:28:51.388001      a           r
  </code></pre>
  
  <p>As you can see, the value in column "prev_status" is the same value for the previous row that matches the same "number_id" (where previous row is after applying date conditions to the "created_dt" column) </p>