title: How to efficiently apply a function to each DataFrame of a Pandas Panel
body: <p>I am trying to apply a function to every DataFrame in a Pandas Panel. I can write it as a loop but the indexing seems to take a long time. I am hoping a builtin Pandas function might be faster.</p>
  
  <p>I have data frames which look like (in reality about 50 rows per column):</p>
  
  <pre><code>mydata = pd.DataFrame( { 'hits' : [ 123, 456,678 ], 'sqerr' : [ 253, 641, 3480] } )
  </code></pre>
  
  <p>They are arranged in a panel with a multi-index key:</p>
  
  <pre><code>mydict = { (0, 20 ) : mydata, (30, 40 ) : moredata }
  mypanel = pd.Panel( mydict )
  </code></pre>
  
  <p>The panel looks like this:</p>
  
  <pre><code>&lt;class 'pandas.core.panel.Panel'&gt;
  Dimensions: 1600 (items) x 48 (major_axis) x 2 (minor_axis)
  Items axis: (-4000, -4000) to (3800, 3800)
  Major_axis axis: 0 to 47
  Minor_axis axis: hits to sqerr
  </code></pre>
  
  <p>I have a function which takes a DataFrame and outputs a number:</p>
  
  <pre><code>def condenser( df ):
      return some_stuff( df['hits'], df['sqerr'] )
  </code></pre>
  
  <p>I want to reduce my Panel to a Series, indexed by my multi-index and with results of my condenser function as its values.</p>
  
  <p>I can do:</p>
  
  <pre><code>intermediate = []
  for k, df in mypanel.iteritems():
      intermediate.append( condenser( df ) )
  
  result = pd.Series( results, index = pypanel.items )
  </code></pre>
  
  <p>which gives the required result, but when I profile it, only 4% of the time is spent in my <code>condenser</code> function. Most of the time is spent in <code>iteritems</code> and <code>__getitem__</code> so I wondered if it could be done better.</p>
  
  <p>I looked at <code>mypanel.apply( condenser, axis = 'items' )</code> but this loops over each column of my DataFrames separately. Is there something which would apply a function to each DataFrame?</p>
  
  <p>P.s. I am using Python 2.7.9 and pandas 0.15.2</p>