title: Generate combinations of values from rolling window in Pandas
body: <p>For every row in my dataframe, I need to create every combination of two values of column <code>a</code> <em>from a three-day sliding window ending at that row</em>. My dataframe is like this:</p>
  
  <pre><code>import pandas as pd    
  df = pd.DataFrame({'a': [1, 2, 3, 4, 5]},
                     index=[pd.Timestamp('20180101'),
                            pd.Timestamp('20180102'),
                            pd.Timestamp('20180103'),
                            pd.Timestamp('20180105'),
                            pd.Timestamp('20180106')])
  </code></pre>
  
  <p>Note that the time index is ragged (inconsistent intervals between rows). The combinations should come out to be:</p>
  
  <pre><code>row0: None
  row1: [(1, 2)]
  row2: [(1, 2), (1, 3), (2, 3)]
  row4: [(3, 4)]
  row5: [(4, 5)]
  </code></pre>
  
  <p>I can do this easily enough <em>without</em> the window, just use <a href="https://docs.python.org/3/library/itertools.html#itertools.combinations" rel="noreferrer"><code>itertools.combinations</code></a> to generate every combination of two elements of column <code>a</code> with:</p>
  
  <pre><code>import itertools as it
  combos = it.combinations(df['a'], 2)
  for c in combos:
      print(c)
  # (1, 2)
  # (1, 3)
  # (1, 4)
  # (1, 5)
  # etc.
  </code></pre>
  
  <p>but I need the windowed version for my application. My best bet so far is to use <a href="https://pandas.pydata.org/pandas-docs/stable/generated/pandas.DataFrame.rolling.html" rel="noreferrer"><code>df.rolling</code></a>. I can do simple things like summing the elements over a three day window with something like:</p>
  
  <pre><code>df.rolling('3d').sum()
  # get [1, 3, 6, 7, 9] which we expect
  </code></pre>
  
  <p>but I can't seem to perform more complicated operations (or return more complicated types than real numbers from an operation) on the rolling window.</p>
  
  <hr>
  
  <h2>Question</h2>
  
  <p>How do I use <code>df.rolling</code> to make combinations over my rolling window? Or is there some other tool to do this?</p>
  
  <hr>
  
  <h2>Attempts</h2>
  
  <p>My thought so far is that there is some way to use <code>df.rolling</code> and <code>df.apply</code> along with <code>it.combinations</code> to generate iterators for each window in my dataframe, and then plug that iterator into a new column of my dataframe. Something like:</p>
  
  <pre><code>df.rolling('3d').apply(lambda x: it.combinations(x, 2))
  </code></pre>
  
  <p>which gives a <code>TypeError</code>:</p>
  
  <blockquote>
    <p>TypeError: must be real number, not itertools.combinations</p>
  </blockquote>
  
  <p>because <a href="https://pandas.pydata.org/pandas-docs/stable/generated/pandas.core.window.Rolling.apply.html" rel="noreferrer"><code>df.rolling.apply</code></a> requires that its argument return a single real value, not an object, nor a list.</p>
  
  <p>I also tried using <code>it.combinations</code> directly on the rolling window:</p>
  
  <pre><code>it.combinations(df.rolling('3d'), 2)
  </code></pre>
  
  <p>which gives:</p>
  
  <blockquote>
    <p>KeyError: 'Column not found: 0'</p>
  </blockquote>
  
  <p>and if I select column <code>a</code> explicitly:</p>
  
  <pre><code>it.combinations(df.rolling('3d')['a'], 2)
  </code></pre>
  
  <p>I get:</p>
  
  <blockquote>
    <p>Exception: Column(s) a already selected</p>
  </blockquote>
  
  <p>So is there maybe a way to define a function that I can call with <code>df.apply</code> that plugs the iterator over my rolling window into a new column for each row of my dataframe? Can I even operate on rows other than the current row in a function passed to <code>apply</code>?</p>