title: Pandas rolling apply using multiple columns
body: <p>I am trying to use a <code>pandas.DataFrame.rolling.apply()</code> rolling function on multiple columns.
  Python version is 3.7, pandas is 1.0.2.</p>
  
  <pre><code>import pandas as pd
  
  #function to calculate
  def masscenter(x):
      print(x); # for debug purposes
      return 0;
  
  #simple DF creation routine
  df = pd.DataFrame( [['02:59:47.000282', 87.60, 739],
                      ['03:00:01.042391', 87.51, 10],
                      ['03:00:01.630182', 87.51, 10],
                      ['03:00:01.635150', 88.00, 792],
                      ['03:00:01.914104', 88.00, 10]], 
                     columns=['stamp', 'price','nQty'])
  df['stamp'] = pd.to_datetime(df2['stamp'], format='%H:%M:%S.%f')
  df.set_index('stamp', inplace=True, drop=True)
  </code></pre>
  
  <p><code>'stamp'</code> is monotonic and unique, <code>'price'</code> is double and contains no NaNs, <code>'nQty'</code> is integer and also contains no NaNs.</p>
  
  <p>So, I need to calculate rolling 'center of mass', i.e. <code>sum(price*nQty)/sum(nQty)</code>.</p>
  
  <p>What I tried so far:</p>
  
  <pre><code>df.apply(masscenter, axis = 1)
  </code></pre>
  
  <p><code>masscenter</code> is be called 5 times with a single row and the output will be like</p>
  
  <pre><code>price     87.6
  nQty     739.0
  Name: 1900-01-01 02:59:47.000282, dtype: float64
  </code></pre>
  
  <p>It is desired input to a <code>masscenter</code>, because I can easily access <code>price</code> and <code>nQty</code> using <code>x[0], x[1]</code>. However, I stuck with <code>rolling.apply()</code>
  Reading the docs
  <a href="https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.rolling.html" rel="noreferrer">DataFrame.rolling()</a> and <a href="https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.window.rolling.Rolling.apply.html" rel="noreferrer">rolling.apply()</a>
  I supposed that using <code>'axis'</code> in <code>rolling()</code> and <code>'raw'</code> in <code>apply</code> one achieves similiar behaviour. A naive approach</p>
  
  <pre><code>rol = df.rolling(window=2)
  rol.apply(masscenter)
  </code></pre>
  
  <p>prints row by row (increasing number of rows up to window size)</p>
  
  <pre><code>stamp
  1900-01-01 02:59:47.000282    87.60
  1900-01-01 03:00:01.042391    87.51
  dtype: float64
  </code></pre>
  
  <p>then</p>
  
  <pre><code>stamp
  1900-01-01 02:59:47.000282    739.0
  1900-01-01 03:00:01.042391     10.0
  dtype: float64
  </code></pre>
  
  <p>So, columns is passed to <code>masscenter</code> separately (expected). </p>
  
  <p>Sadly, in the docs there is barely any info about <code>'axis'</code>. However the next variant was, obviously</p>
  
  <pre><code>rol = df.rolling(window=2, axis = 1)
  rol.apply(masscenter)
  </code></pre>
  
  <p>Never calls <code>masscenter</code> and raises <code>ValueError in rol.apply(..)</code></p>
  
  <pre><code>&gt; Length of passed values is 1, index implies 5
  </code></pre>
  
  <p>I admit that I'm not sure about <code>'axis'</code> parameter and how it works due to lack of documentation. It is the first part of the question:
  <strong>What is going on here? How to use 'axis' properly? What it is designed for?</strong></p>
  
  <p>Of course, there were answers previously, namely:</p>
  
  <p><a href="https://stackoverflow.com/questions/13331698/how-to-apply-a-function-to-two-columns-of-pandas-dataframe">How-to-apply-a-function-to-two-columns-of-pandas-dataframe</a><br>
  It works for the whole DataFrame, not Rolling.</p>
  
  <p><a href="https://stackoverflow.com/questions/38878917/how-to-invoke-pandas-rolling-apply-with-parameters-from-multiple-column">How-to-invoke-pandas-rolling-apply-with-parameters-from-multiple-column</a><br>
  The answer suggests to write my own roll function, but the culprit for me is the same as asked in  <a href="https://stackoverflow.com/questions/38878917/how-to-invoke-pandas-rolling-apply-with-parameters-from-multiple-column#comment99035791_38879051">comments</a>: what if one needs to use offset window size (e.g. <code>'1T'</code>) for non-uniform timestamps?<br>
  I don't like the idea to reinvent the wheel from scratch. Also I'd like to use pandas for everything to prevent inconsistency between sets obtained from pandas and 'self-made roll'.
  There is another answer to that question, suggessting to populate dataframe separately and calculate whatever I need, but it will not work: the size of stored data will be enormous.
  The same idea presented here:<br>
  <a href="https://stackoverflow.com/questions/59574934/apply-rolling-function-on-pandas-dataframe-with-multiple-arguments">Apply-rolling-function-on-pandas-dataframe-with-multiple-arguments</a></p>
  
  <p>Another Q &amp; A posted here<br>
  <a href="https://stackoverflow.com/questions/51615849/pandas-using-rolling-on-multiple-columns">Pandas-using-rolling-on-multiple-columns</a><br>
  It is good and the closest to my problem, but again, there is no possibility to use offset window sizes (<code>window = '1T'</code>).</p>
  
  <p>Some of the answers were asked before pandas 1.0 came out, and given that docs could be much better, I hope it is possible to roll over multiple columns simultaneously now.</p>
  
  <p>The second part of the question is:
  <strong>Is there any possibility to roll over multiple columns simultaneously using pandas 1.0.x with offset window size?</strong></p>
  
  <p>Thank you very much.</p>