<p dir="auto">So here's my setup (using pandas 0.16.2):</p>
<div class="highlight highlight-source-python notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="&gt;&gt;&gt; midx = pd.MultiIndex.from_product([['bar', 'baz', 'foo', 'qux'], ['one', 'two']],names=['first','second'])
&gt;&gt;&gt; df = pd.DataFrame(np.random.randint(10,size=(8,8)),index=midx)

&gt;&gt;&gt; df 
              0  1  2  3  4  5  6  7
first second                        
bar   one     0  5  5  5  6  2  6  8
      two     2  6  9  0  3  6  7  9
baz   one     9  0  9  9  2  5  7  4
      two     4  8  1  2  9  2  8  1
foo   one     2  7  3  6  5  5  5  2
      two     3  4  6  2  7  7  1  2
qux   one     0  8  5  9  5  5  7  3
      two     7  4  0  7  3  6  8  6"><pre class="notranslate"><span class="pl-c1">&gt;&gt;</span><span class="pl-c1">&gt;</span> <span class="pl-s1">midx</span> <span class="pl-c1">=</span> <span class="pl-s1">pd</span>.<span class="pl-v">MultiIndex</span>.<span class="pl-en">from_product</span>([[<span class="pl-s">'bar'</span>, <span class="pl-s">'baz'</span>, <span class="pl-s">'foo'</span>, <span class="pl-s">'qux'</span>], [<span class="pl-s">'one'</span>, <span class="pl-s">'two'</span>]],<span class="pl-s1">names</span><span class="pl-c1">=</span>[<span class="pl-s">'first'</span>,<span class="pl-s">'second'</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-s1">np</span>.<span class="pl-s1">random</span>.<span class="pl-en">randint</span>(<span class="pl-c1">10</span>,<span class="pl-s1">size</span><span class="pl-c1">=</span>(<span class="pl-c1">8</span>,<span class="pl-c1">8</span>)),<span class="pl-s1">index</span><span class="pl-c1">=</span><span class="pl-s1">midx</span>)

<span class="pl-c1">&gt;&gt;</span><span class="pl-c1">&gt;</span> <span class="pl-s1">df</span> 
              <span class="pl-c1">0</span>  <span class="pl-c1">1</span>  <span class="pl-c1">2</span>  <span class="pl-c1">3</span>  <span class="pl-c1">4</span>  <span class="pl-c1">5</span>  <span class="pl-c1">6</span>  <span class="pl-c1">7</span>
<span class="pl-s1">first</span> <span class="pl-s1">second</span>                        
<span class="pl-s1">bar</span>   <span class="pl-s1">one</span>     <span class="pl-c1">0</span>  <span class="pl-c1">5</span>  <span class="pl-c1">5</span>  <span class="pl-c1">5</span>  <span class="pl-c1">6</span>  <span class="pl-c1">2</span>  <span class="pl-c1">6</span>  <span class="pl-c1">8</span>
      <span class="pl-s1">two</span>     <span class="pl-c1">2</span>  <span class="pl-c1">6</span>  <span class="pl-c1">9</span>  <span class="pl-c1">0</span>  <span class="pl-c1">3</span>  <span class="pl-c1">6</span>  <span class="pl-c1">7</span>  <span class="pl-c1">9</span>
<span class="pl-s1">baz</span>   <span class="pl-s1">one</span>     <span class="pl-c1">9</span>  <span class="pl-c1">0</span>  <span class="pl-c1">9</span>  <span class="pl-c1">9</span>  <span class="pl-c1">2</span>  <span class="pl-c1">5</span>  <span class="pl-c1">7</span>  <span class="pl-c1">4</span>
      <span class="pl-s1">two</span>     <span class="pl-c1">4</span>  <span class="pl-c1">8</span>  <span class="pl-c1">1</span>  <span class="pl-c1">2</span>  <span class="pl-c1">9</span>  <span class="pl-c1">2</span>  <span class="pl-c1">8</span>  <span class="pl-c1">1</span>
<span class="pl-s1">foo</span>   <span class="pl-s1">one</span>     <span class="pl-c1">2</span>  <span class="pl-c1">7</span>  <span class="pl-c1">3</span>  <span class="pl-c1">6</span>  <span class="pl-c1">5</span>  <span class="pl-c1">5</span>  <span class="pl-c1">5</span>  <span class="pl-c1">2</span>
      <span class="pl-s1">two</span>     <span class="pl-c1">3</span>  <span class="pl-c1">4</span>  <span class="pl-c1">6</span>  <span class="pl-c1">2</span>  <span class="pl-c1">7</span>  <span class="pl-c1">7</span>  <span class="pl-c1">1</span>  <span class="pl-c1">2</span>
<span class="pl-s1">qux</span>   <span class="pl-s1">one</span>     <span class="pl-c1">0</span>  <span class="pl-c1">8</span>  <span class="pl-c1">5</span>  <span class="pl-c1">9</span>  <span class="pl-c1">5</span>  <span class="pl-c1">5</span>  <span class="pl-c1">7</span>  <span class="pl-c1">3</span>
      <span class="pl-s1">two</span>     <span class="pl-c1">7</span>  <span class="pl-c1">4</span>  <span class="pl-c1">0</span>  <span class="pl-c1">7</span>  <span class="pl-c1">3</span>  <span class="pl-c1">6</span>  <span class="pl-c1">8</span>  <span class="pl-c1">6</span></pre></div>
<p dir="auto">I recently found that I can select multiple levels by indexing with a tuple of tuples</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="&gt;&gt;&gt; df.loc[( ('bar','baz'),  ), :]
              0  1  2  3  4  5  6  7
first second                        
bar   one     0  5  5  5  6  2  6  8
      two     2  6  9  0  3  6  7  9
baz   one     9  0  9  9  2  5  7  4
      two     4  8  1  2  9  2  8  1"><pre class="notranslate"><code class="notranslate">&gt;&gt;&gt; df.loc[( ('bar','baz'),  ), :]
              0  1  2  3  4  5  6  7
first second                        
bar   one     0  5  5  5  6  2  6  8
      two     2  6  9  0  3  6  7  9
baz   one     9  0  9  9  2  5  7  4
      two     4  8  1  2  9  2  8  1
</code></pre></div>
<p dir="auto">Or even select at multiple depths of levels</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="&gt;&gt;&gt; df.loc[( ('bar','baz'), ('one',) ), :]
              0  1  2  3  4  5  6  7
first second                        
bar   one     0  5  5  5  6  2  6  8
baz   one     9  0  9  9  2  5  7  4"><pre class="notranslate"><code class="notranslate">&gt;&gt;&gt; df.loc[( ('bar','baz'), ('one',) ), :]
              0  1  2  3  4  5  6  7
first second                        
bar   one     0  5  5  5  6  2  6  8
baz   one     9  0  9  9  2  5  7  4
</code></pre></div>
<p dir="auto">The issue is this: if I add any levels to the index tuple that don't exist in the dataframe, pandas drops them silently</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="&gt;&gt;&gt; df.loc[( ('bar','baz','xyz'), ('one',) ), :]
              0  1  2  3  4  5  6  7
first second                        
bar   one     0  5  5  5  6  2  6  8
baz   one     9  0  9  9  2  5  7  4"><pre class="notranslate"><code class="notranslate">&gt;&gt;&gt; df.loc[( ('bar','baz','xyz'), ('one',) ), :]
              0  1  2  3  4  5  6  7
first second                        
bar   one     0  5  5  5  6  2  6  8
baz   one     9  0  9  9  2  5  7  4
</code></pre></div>
<p dir="auto">It seems to me like this should raise an exception since</p>
<ol dir="auto">
<li>The shape of the dataframe that is returned in this instance is not what you'd expect</li>
<li>There's no way to unambiguously fill the returned dataframe with NaNs where a level didn't exist (as is done in the case where there is only a single level index)</li>
</ol>
<p dir="auto">xref <a class="issue-link js-issue-link" data-error-text="Failed to load title" data-id="9407965" data-permission-text="Title is private" data-url="https://github.com/pandas-dev/pandas/issues/2567" data-hovercard-type="issue" data-hovercard-url="/pandas-dev/pandas/issues/2567/hovercard" href="https://github.com/pandas-dev/pandas/issues/2567">#2567</a></p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="In [27]: data = pd.DataFrame({'hr1': [514, 573], 'hr2': [545, 526],
    ...:                       'team': ['Red Sox', 'Yankees'],
    ...:                       'year1': [2007, 2008], 'year2': [2008, 2008]})
    ...: 

In [28]: data
Out[28]: 
   hr1  hr2     team  year1  year2
0  514  545  Red Sox   2007   2008
1  573  526  Yankees   2008   2008

In [29]: pd.lreshape(data, {'year': ['year1', 'year2'], 'hr': ['hr1', 'hr2']})
Out[29]: 
      team  year   hr
0  Red Sox  2007  514
1  Yankees  2008  573
2  Red Sox  2008  545
3  Yankees  2008  526

In [30]: pd.wide_to_long(data, ['hr', 'year'], 'team', 'index')
Out[30]: 
                hr  year
team    index           
Red Sox 1      514  2007
Yankees 1      573  2008
Red Sox 2      545  2008
Yankees 2      526  2008"><pre class="notranslate"><code class="notranslate">In [27]: data = pd.DataFrame({'hr1': [514, 573], 'hr2': [545, 526],
    ...:                       'team': ['Red Sox', 'Yankees'],
    ...:                       'year1': [2007, 2008], 'year2': [2008, 2008]})
    ...: 

In [28]: data
Out[28]: 
   hr1  hr2     team  year1  year2
0  514  545  Red Sox   2007   2008
1  573  526  Yankees   2008   2008

In [29]: pd.lreshape(data, {'year': ['year1', 'year2'], 'hr': ['hr1', 'hr2']})
Out[29]: 
      team  year   hr
0  Red Sox  2007  514
1  Yankees  2008  573
2  Red Sox  2008  545
3  Yankees  2008  526

In [30]: pd.wide_to_long(data, ['hr', 'year'], 'team', 'index')
Out[30]: 
                hr  year
team    index           
Red Sox 1      514  2007
Yankees 1      573  2008
Red Sox 2      545  2008
Yankees 2      526  2008
</code></pre></div>
<p dir="auto">So we should drop one of these.</p>