<h4 dir="auto">Sample code</h4>
<div class="highlight highlight-source-python notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="import pandas as pd
from pandas.api.types import CategoricalDtype
import numpy as np

# Load data
df = pd.read_excel('http://pbpython.com/extras/sales-funnel.xlsx')
# Make categories
df[&quot;Status&quot;] = pd.Categorical(df[&quot;Status&quot;], categories=[&quot;won&quot;,&quot;pending&quot;,&quot;presented&quot;,&quot;declined&quot;], ordered=False)

# Create pivot table - WORKS FINE
pd.pivot_table(df, index=['Manager', 'Status'], 
               values=['Quantity', 'Price'], 
               aggfunc={'Quantity': len, 'Price': [np.sum, np.mean]}, 
               fill_value=0, 
               margins=False)

# Here we make the only change: set parameter margins=True

# Create pivot table - FAILS on KeyError: 'Level None not found'
pd.pivot_table(df, index=['Manager', 'Status'], 
               values=['Quantity', 'Price'], 
               aggfunc={'Quantity': len, 'Price': [np.sum, np.mean]}, 
               fill_value=0, 
               margins=True)"><pre class="notranslate"><span class="pl-k">import</span> <span class="pl-s1">pandas</span> <span class="pl-k">as</span> <span class="pl-s1">pd</span>
<span class="pl-k">from</span> <span class="pl-s1">pandas</span>.<span class="pl-s1">api</span>.<span class="pl-s1">types</span> <span class="pl-k">import</span> <span class="pl-v">CategoricalDtype</span>
<span class="pl-k">import</span> <span class="pl-s1">numpy</span> <span class="pl-k">as</span> <span class="pl-s1">np</span>

<span class="pl-c"># Load data</span>
<span class="pl-s1">df</span> <span class="pl-c1">=</span> <span class="pl-s1">pd</span>.<span class="pl-en">read_excel</span>(<span class="pl-s">'http://pbpython.com/extras/sales-funnel.xlsx'</span>)
<span class="pl-c"># Make categories</span>
<span class="pl-s1">df</span>[<span class="pl-s">"Status"</span>] <span class="pl-c1">=</span> <span class="pl-s1">pd</span>.<span class="pl-v">Categorical</span>(<span class="pl-s1">df</span>[<span class="pl-s">"Status"</span>], <span class="pl-s1">categories</span><span class="pl-c1">=</span>[<span class="pl-s">"won"</span>,<span class="pl-s">"pending"</span>,<span class="pl-s">"presented"</span>,<span class="pl-s">"declined"</span>], <span class="pl-s1">ordered</span><span class="pl-c1">=</span><span class="pl-c1">False</span>)

<span class="pl-c"># Create pivot table - WORKS FINE</span>
<span class="pl-s1">pd</span>.<span class="pl-en">pivot_table</span>(<span class="pl-s1">df</span>, <span class="pl-s1">index</span><span class="pl-c1">=</span>[<span class="pl-s">'Manager'</span>, <span class="pl-s">'Status'</span>], 
               <span class="pl-s1">values</span><span class="pl-c1">=</span>[<span class="pl-s">'Quantity'</span>, <span class="pl-s">'Price'</span>], 
               <span class="pl-s1">aggfunc</span><span class="pl-c1">=</span>{<span class="pl-s">'Quantity'</span>: <span class="pl-s1">len</span>, <span class="pl-s">'Price'</span>: [<span class="pl-s1">np</span>.<span class="pl-s1">sum</span>, <span class="pl-s1">np</span>.<span class="pl-s1">mean</span>]}, 
               <span class="pl-s1">fill_value</span><span class="pl-c1">=</span><span class="pl-c1">0</span>, 
               <span class="pl-s1">margins</span><span class="pl-c1">=</span><span class="pl-c1">False</span>)

<span class="pl-c"># Here we make the only change: set parameter margins=True</span>

<span class="pl-c"># Create pivot table - FAILS on KeyError: 'Level None not found'</span>
<span class="pl-s1">pd</span>.<span class="pl-en">pivot_table</span>(<span class="pl-s1">df</span>, <span class="pl-s1">index</span><span class="pl-c1">=</span>[<span class="pl-s">'Manager'</span>, <span class="pl-s">'Status'</span>], 
               <span class="pl-s1">values</span><span class="pl-c1">=</span>[<span class="pl-s">'Quantity'</span>, <span class="pl-s">'Price'</span>], 
               <span class="pl-s1">aggfunc</span><span class="pl-c1">=</span>{<span class="pl-s">'Quantity'</span>: <span class="pl-s1">len</span>, <span class="pl-s">'Price'</span>: [<span class="pl-s1">np</span>.<span class="pl-s1">sum</span>, <span class="pl-s1">np</span>.<span class="pl-s1">mean</span>]}, 
               <span class="pl-s1">fill_value</span><span class="pl-c1">=</span><span class="pl-c1">0</span>, 
               <span class="pl-s1">margins</span><span class="pl-c1">=</span><span class="pl-c1">True</span>)</pre></div>
<h4 dir="auto">Problem description</h4>
<p dir="auto">Pivot table fails on exception, when margins are set True on previous example.</p>
<p dir="auto">Thrown exception is:<br>
<code class="notranslate">KeyError: 'Level None not found'</code></p>
<h4 dir="auto">Expected Output</h4>
<p dir="auto">pivot_table with margins=True should work correctly<br>
OR<br>
report intuitive error<br>
OR<br>
documentation should be clearly updated to avoid such a problem</p>
<h4 dir="auto">Output of <code class="notranslate">pd.show_versions()</code></h4>
<details>
INSTALLED VERSIONS
------------------
commit: None
python: 3.6.3.final.0
python-bits: 64
OS: Windows
OS-release: 10
machine: AMD64
processor: Intel64 Family 6 Model 94 Stepping 3, GenuineIntel
byteorder: little
LC_ALL: None
LANG: None
LOCALE: None.None
<p dir="auto">pandas: 0.21.0<br>
pytest: 3.3.0<br>
pip: 9.0.1<br>
setuptools: 36.5.0.post20170921<br>
Cython: 0.27.3<br>
numpy: 1.13.3<br>
scipy: 1.0.0<br>
pyarrow: None<br>
xarray: None<br>
IPython: 6.2.1<br>
sphinx: 1.6.3<br>
patsy: 0.4.1<br>
dateutil: 2.6.1<br>
pytz: 2017.3<br>
blosc: None<br>
bottleneck: 1.2.1<br>
tables: 3.4.2<br>
numexpr: 2.6.4<br>
feather: None<br>
matplotlib: 2.1.0<br>
openpyxl: 2.4.9<br>
xlrd: 1.1.0<br>
xlwt: 1.3.0<br>
xlsxwriter: 1.0.2<br>
lxml: 4.1.1<br>
bs4: 4.6.0<br>
html5lib: 0.999999999<br>
sqlalchemy: 1.1.13<br>
pymysql: None<br>
psycopg2: None<br>
jinja2: 2.10<br>
s3fs: None<br>
fastparquet: None<br>
pandas_gbq: None<br>
pandas_datareader: None</p>
</details>
<p dir="auto">When applying multiple aggregations to columns and setting margins=True I receive a KeyError. I believe that because multiple aggregations are applied the columns become a MultiIndex, which is unexpected when computing margins.</p>
<div class="highlight highlight-source-python notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="&gt;&gt;&gt; import pandas as pd
&gt;&gt;&gt; import numpy as np
&gt;&gt;&gt; import random


&gt;&gt;&gt; df = pd.DataFrame({'random1': [random.random() for i in range(10)],
                       'random2': [random.random() for i in range(10)],
                       'type': ['duck', 'bird']*5},
                index=range(10,20))

&gt;&gt;&gt; df.pivot_table(index='type', 
                   aggfunc={'random1': [np.median, np.mean], 
                            'random2': np.sum}, 
                   margins=True)

KeyError                                  Traceback (most recent call last)
&lt;ipython-input&gt; in &lt;module&gt;()
      3                aggfunc={'random1': [np.median, np.mean], 
      4                         'random2': np.sum}, 
----&gt; 5                margins=True)

/pandas/util/decorators.pyc in wrapper(*args, **kwargs)
     86                 else:
     87                     kwargs[new_arg_name] = new_arg_value
---&gt; 88             return func(*args, **kwargs)
     89         return wrapper
     90     return _deprecate_kwarg

/pandas/util/decorators.pyc in wrapper(*args, **kwargs)
     86                 else:
     87                     kwargs[new_arg_name] = new_arg_value
---&gt; 88             return func(*args, **kwargs)
     89         return wrapper
     90     return _deprecate_kwarg

/pandas/tools/pivot.pyc in pivot_table(data, values, index, columns, aggfunc, fill_value, margins, dropna)
    145     if margins:
    146         table = _add_margins(table, data, values, rows=index,
--&gt; 147                              cols=columns, aggfunc=aggfunc)
    148 
    149     # discard the top level

/pandas/tools/pivot.pyc in _add_margins(table, data, values, rows, cols, aggfunc)
    189             row_margin[k] = grand_margin[k]
    190         else:
--&gt; 191             row_margin[k] = grand_margin[k[0]]
    192 
    193     margin_dummy = DataFrame(row_margin, columns=[key]).T

KeyError: 'random1'
"><pre class="notranslate"><span class="pl-c1">&gt;&gt;</span><span class="pl-c1">&gt;</span> <span class="pl-k">import</span> <span class="pl-s1">pandas</span> <span class="pl-k">as</span> <span class="pl-s1">pd</span>
<span class="pl-c1">&gt;&gt;</span><span class="pl-c1">&gt;</span> <span class="pl-k">import</span> <span class="pl-s1">numpy</span> <span class="pl-k">as</span> <span class="pl-s1">np</span>
<span class="pl-c1">&gt;&gt;</span><span class="pl-c1">&gt;</span> <span class="pl-k">import</span> <span class="pl-s1">random</span>


<span class="pl-c1">&gt;&gt;</span><span class="pl-c1">&gt;</span> <span class="pl-s1">df</span> <span class="pl-c1">=</span> <span class="pl-s1">pd</span>.<span class="pl-v">DataFrame</span>({<span class="pl-s">'random1'</span>: [<span class="pl-s1">random</span>.<span class="pl-en">random</span>() <span class="pl-k">for</span> <span class="pl-s1">i</span> <span class="pl-c1">in</span> <span class="pl-en">range</span>(<span class="pl-c1">10</span>)],
                       <span class="pl-s">'random2'</span>: [<span class="pl-s1">random</span>.<span class="pl-en">random</span>() <span class="pl-k">for</span> <span class="pl-s1">i</span> <span class="pl-c1">in</span> <span class="pl-en">range</span>(<span class="pl-c1">10</span>)],
                       <span class="pl-s">'type'</span>: [<span class="pl-s">'duck'</span>, <span class="pl-s">'bird'</span>]<span class="pl-c1">*</span><span class="pl-c1">5</span>},
                <span class="pl-s1">index</span><span class="pl-c1">=</span><span class="pl-en">range</span>(<span class="pl-c1">10</span>,<span class="pl-c1">20</span>))

<span class="pl-c1">&gt;&gt;</span><span class="pl-c1">&gt;</span> <span class="pl-s1">df</span>.<span class="pl-en">pivot_table</span>(<span class="pl-s1">index</span><span class="pl-c1">=</span><span class="pl-s">'type'</span>, 
                   <span class="pl-s1">aggfunc</span><span class="pl-c1">=</span>{<span class="pl-s">'random1'</span>: [<span class="pl-s1">np</span>.<span class="pl-s1">median</span>, <span class="pl-s1">np</span>.<span class="pl-s1">mean</span>], 
                            <span class="pl-s">'random2'</span>: <span class="pl-s1">np</span>.<span class="pl-s1">sum</span>}, 
                   <span class="pl-s1">margins</span><span class="pl-c1">=</span><span class="pl-c1">True</span>)

<span class="pl-v">KeyError</span>                                  <span class="pl-v">Traceback</span> (<span class="pl-s1">most</span> <span class="pl-s1">recent</span> <span class="pl-s1">call</span> <span class="pl-s1">last</span>)
<span class="pl-c1">&lt;</span><span class="pl-s1">ipython</span><span class="pl-c1">-</span><span class="pl-s1">input</span><span class="pl-c1">&gt;</span> <span class="pl-s1">in</span> <span class="pl-c1">&lt;</span><span class="pl-s1">module</span><span class="pl-c1">&gt;</span>()
      <span class="pl-c1">3</span>                <span class="pl-s1">aggfunc</span><span class="pl-c1">=</span>{<span class="pl-s">'random1'</span>: [<span class="pl-s1">np</span>.<span class="pl-s1">median</span>, <span class="pl-s1">np</span>.<span class="pl-s1">mean</span>], 
      <span class="pl-c1">4</span>                         <span class="pl-s">'random2'</span>: <span class="pl-s1">np</span>.<span class="pl-s1">sum</span>}, 
<span class="pl-c1">-</span><span class="pl-c1">-</span><span class="pl-c1">-</span><span class="pl-c1">-</span><span class="pl-c1">&gt;</span> <span class="pl-c1">5</span>                <span class="pl-s1">margins</span><span class="pl-c1">=</span><span class="pl-c1">True</span>)

<span class="pl-c1">/</span><span class="pl-s1">pandas</span><span class="pl-c1">/</span><span class="pl-s1">util</span><span class="pl-c1">/</span><span class="pl-s1">decorators</span>.<span class="pl-s1">pyc</span> <span class="pl-c1">in</span> <span class="pl-en">wrapper</span>(<span class="pl-c1">*</span><span class="pl-s1">args</span>, <span class="pl-c1">**</span><span class="pl-s1">kwargs</span>)
     <span class="pl-c1">86</span>                 <span class="pl-s1">else</span>:
     <span class="pl-c1">87</span>                     <span class="pl-s1">kwargs</span>[<span class="pl-s1">new_arg_name</span>] <span class="pl-c1">=</span> <span class="pl-s1">new_arg_value</span>
<span class="pl-c1">-</span><span class="pl-c1">-</span><span class="pl-c1">-</span><span class="pl-c1">&gt;</span> <span class="pl-c1">88</span>             <span class="pl-s1">return</span> <span class="pl-en">func</span>(<span class="pl-c1">*</span><span class="pl-s1">args</span>, <span class="pl-c1">**</span><span class="pl-s1">kwargs</span>)
     <span class="pl-c1">89</span>         <span class="pl-k">return</span> <span class="pl-s1">wrapper</span>
     <span class="pl-c1">90</span>     <span class="pl-s1">return</span> <span class="pl-s1">_deprecate_kwarg</span>

<span class="pl-c1">/</span><span class="pl-s1">pandas</span><span class="pl-c1">/</span><span class="pl-s1">util</span><span class="pl-c1">/</span><span class="pl-s1">decorators</span>.<span class="pl-s1">pyc</span> <span class="pl-c1">in</span> <span class="pl-en">wrapper</span>(<span class="pl-c1">*</span><span class="pl-s1">args</span>, <span class="pl-c1">**</span><span class="pl-s1">kwargs</span>)
     <span class="pl-c1">86</span>                 <span class="pl-s1">else</span>:
     <span class="pl-c1">87</span>                     <span class="pl-s1">kwargs</span>[<span class="pl-s1">new_arg_name</span>] <span class="pl-c1">=</span> <span class="pl-s1">new_arg_value</span>
<span class="pl-c1">-</span><span class="pl-c1">-</span><span class="pl-c1">-</span><span class="pl-c1">&gt;</span> <span class="pl-c1">88</span>             <span class="pl-s1">return</span> <span class="pl-en">func</span>(<span class="pl-c1">*</span><span class="pl-s1">args</span>, <span class="pl-c1">**</span><span class="pl-s1">kwargs</span>)
     <span class="pl-c1">89</span>         <span class="pl-k">return</span> <span class="pl-s1">wrapper</span>
     <span class="pl-c1">90</span>     <span class="pl-s1">return</span> <span class="pl-s1">_deprecate_kwarg</span>

<span class="pl-c1">/</span><span class="pl-s1">pandas</span><span class="pl-c1">/</span><span class="pl-s1">tools</span><span class="pl-c1">/</span><span class="pl-s1">pivot</span>.<span class="pl-s1">pyc</span> <span class="pl-c1">in</span> <span class="pl-en">pivot_table</span>(<span class="pl-s1">data</span>, <span class="pl-s1">values</span>, <span class="pl-s1">index</span>, <span class="pl-s1">columns</span>, <span class="pl-s1">aggfunc</span>, <span class="pl-s1">fill_value</span>, <span class="pl-s1">margins</span>, <span class="pl-s1">dropna</span>)
    <span class="pl-c1">145</span>     <span class="pl-k">if</span> <span class="pl-s1">margins</span>:
    <span class="pl-c1">146</span>         <span class="pl-s1">table</span> <span class="pl-c1">=</span> <span class="pl-en">_add_margins</span>(<span class="pl-s1">table</span>, <span class="pl-s1">data</span>, <span class="pl-s1">values</span>, <span class="pl-s1">rows</span><span class="pl-c1">=</span><span class="pl-s1">index</span>,
<span class="pl-c1">-</span><span class="pl-c1">-</span><span class="pl-c1">&gt;</span> <span class="pl-c1">147</span>                              <span class="pl-s1">cols</span><span class="pl-c1">=</span><span class="pl-s1">columns</span>, <span class="pl-s1">aggfunc</span><span class="pl-c1">=</span><span class="pl-s1">aggfunc</span>)
    <span class="pl-c1">148</span> 
    <span class="pl-c1">149</span>     <span class="pl-c"># discard the top level</span>

<span class="pl-c1">/</span><span class="pl-s1">pandas</span><span class="pl-c1">/</span><span class="pl-s1">tools</span><span class="pl-c1">/</span><span class="pl-s1">pivot</span>.<span class="pl-s1">pyc</span> <span class="pl-c1">in</span> <span class="pl-en">_add_margins</span>(<span class="pl-s1">table</span>, <span class="pl-s1">data</span>, <span class="pl-s1">values</span>, <span class="pl-s1">rows</span>, <span class="pl-s1">cols</span>, <span class="pl-s1">aggfunc</span>)
    <span class="pl-c1">189</span>             <span class="pl-s1">row_margin</span>[<span class="pl-s1">k</span>] <span class="pl-c1">=</span> <span class="pl-s1">grand_margin</span>[<span class="pl-s1">k</span>]
    <span class="pl-c1">190</span>         <span class="pl-k">else</span>:
<span class="pl-c1">-</span><span class="pl-c1">-</span><span class="pl-c1">&gt;</span> <span class="pl-c1">191</span>             <span class="pl-s1">row_margin</span>[<span class="pl-s1">k</span>] <span class="pl-c1">=</span> <span class="pl-s1">grand_margin</span>[<span class="pl-s1">k</span>[<span class="pl-c1">0</span>]]
    <span class="pl-c1">192</span> 
    <span class="pl-c1">193</span>     <span class="pl-s1">margin_dummy</span> <span class="pl-c1">=</span> <span class="pl-v">DataFrame</span>(<span class="pl-s1">row_margin</span>, <span class="pl-s1">columns</span><span class="pl-c1">=</span>[<span class="pl-s1">key</span>]).<span class="pl-v">T</span>

<span class="pl-v">KeyError</span>: <span class="pl-s">'random1'</span></pre></div>
<p dir="auto">The <em>exact</em> same error occurs with</p>
<div class="highlight highlight-source-python notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="aggfunc={'random1': {'median': np.median, 'mean': np.mean}, 
         'random2': np.sum}"><pre class="notranslate"><span class="pl-s1">aggfunc</span><span class="pl-c1">=</span>{<span class="pl-s">'random1'</span>: {<span class="pl-s">'median'</span>: <span class="pl-s1">np</span>.<span class="pl-s1">median</span>, <span class="pl-s">'mean'</span>: <span class="pl-s1">np</span>.<span class="pl-s1">mean</span>}, 
         <span class="pl-s">'random2'</span>: <span class="pl-s1">np</span>.<span class="pl-s1">sum</span>}</pre></div>
<p dir="auto">These errors do not occur when margins=False<br>
This is using pandas version 0.15.2. I have not seen any changes which would lead me to believe it is be fixed in master.</p>
<p dir="auto">Happy to create a PR, although I haven't done one before.</p>