<p dir="auto">I feel like I've encountered a bug. In the following scenario, the first <code class="notranslate">sort_index</code> call behaves as expected, but the second does not. Does someone know what the difference is here?</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="In [1]: import pandas as pd

In [2]: pd.__version__
Out[2]: '0.15.2'

In [3]: tuples = [(' foo', 'bar'), ('foo', 'bar'), (' foo ()', 'bar')]

In [4]: cols = pd.MultiIndex.from_tuples(tuples)

In [5]: df = pd.DataFrame(index=cols, data={'baz': [0, 1, 2]})

In [6]: df
Out[6]: 
             baz
 foo    bar    0
foo     bar    1
 foo () bar    2

In [7]: df.sort_index()
Out[7]: 
             baz
 foo    bar    0
 foo () bar    2
foo     bar    1

In [8]: tuples = [(' foo', 'bar'), ('foo', 'bar')]

In [9]: cols = pd.MultiIndex.from_tuples(tuples)

In [10]: df = pd.DataFrame(index=cols, data={'baz': [0, 1]})

In [11]: df
Out[11]: 
          baz
 foo bar    0
foo  bar    1

In [12]: df.ix[(' foo ()', 'bar'), 'baz'] = 2

In [13]: df
Out[13]: 
             baz
 foo    bar    0
foo     bar    1
 foo () bar    2

In [14]: df.sort_index()
Out[14]: 
             baz
 foo    bar    0
foo     bar    1
 foo () bar    2"><pre class="notranslate"><code class="notranslate">In [1]: import pandas as pd

In [2]: pd.__version__
Out[2]: '0.15.2'

In [3]: tuples = [(' foo', 'bar'), ('foo', 'bar'), (' foo ()', 'bar')]

In [4]: cols = pd.MultiIndex.from_tuples(tuples)

In [5]: df = pd.DataFrame(index=cols, data={'baz': [0, 1, 2]})

In [6]: df
Out[6]: 
             baz
 foo    bar    0
foo     bar    1
 foo () bar    2

In [7]: df.sort_index()
Out[7]: 
             baz
 foo    bar    0
 foo () bar    2
foo     bar    1

In [8]: tuples = [(' foo', 'bar'), ('foo', 'bar')]

In [9]: cols = pd.MultiIndex.from_tuples(tuples)

In [10]: df = pd.DataFrame(index=cols, data={'baz': [0, 1]})

In [11]: df
Out[11]: 
          baz
 foo bar    0
foo  bar    1

In [12]: df.ix[(' foo ()', 'bar'), 'baz'] = 2

In [13]: df
Out[13]: 
             baz
 foo    bar    0
foo     bar    1
 foo () bar    2

In [14]: df.sort_index()
Out[14]: 
             baz
 foo    bar    0
foo     bar    1
 foo () bar    2
</code></pre></div>
<p dir="auto">Inspired by some bug reports around multiindex sortedness (<a href="http://stackoverflow.com/questions/31427466/ensuring-lexicographical-sort-in-pandas-multiindex" rel="nofollow">http://stackoverflow.com/questions/31427466/ensuring-lexicographical-sort-in-pandas-multiindex</a>, <a class="issue-link js-issue-link" data-error-text="Failed to load title" data-id="96509289" data-permission-text="Title is private" data-url="https://github.com/pandas-dev/pandas/issues/10651" data-hovercard-type="issue" data-hovercard-url="/pandas-dev/pandas/issues/10651/hovercard" href="https://github.com/pandas-dev/pandas/issues/10651">#10651</a>, <a class="issue-link js-issue-link" data-error-text="Failed to load title" data-id="53730230" data-permission-text="Title is private" data-url="https://github.com/pandas-dev/pandas/issues/9212" data-hovercard-type="issue" data-hovercard-url="/pandas-dev/pandas/issues/9212/hovercard" href="https://github.com/pandas-dev/pandas/issues/9212">#9212</a>), I found that <code class="notranslate">sort_index()</code> sometimes can't make a multiindex ready for slicing, but <code class="notranslate">sort_index(level=0)</code> (so does <code class="notranslate">sortlevel()</code>) can.</p>
<div class="highlight highlight-source-python notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="In [119]: pd.__version__
Out[119]: u'0.18.1'

In [120]: df = pd.DataFrame({'col1': ['b','d','b','a'], 'col2': [3,1,1,2], 'data':['one','two','three','four']})

In [121]: df2 = df.set_index(['col1','col2'])

In [122]: df2.index.set_levels(['b','d','a'], level='col1', inplace=True)

In [123]: df2.index.set_labels([0,1,0,2], level='col1', inplace=True)

In [124]: df2.sortlevel()
Out[124]:
            data
col1 col2
b    1     three
     3       one
d    1       two
a    2      four

In [125]: df2.sort_index()
Out[125]:
            data
col1 col2
a    2      four
b    1     three
     3       one
d    1       two

In [126]: df2.sort_index(level=0)
Out[126]:
            data
col1 col2
b    1     three
     3       one
d    1       two
a    2      four"><pre class="notranslate"><span class="pl-v">In</span> [<span class="pl-c1">119</span>]: <span class="pl-s1">pd</span>.<span class="pl-s1">__version__</span>
<span class="pl-v">Out</span>[<span class="pl-c1">119</span>]: <span class="pl-s">u'0.18.1'</span>

<span class="pl-v">In</span> [<span class="pl-c1">120</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">'col1'</span>: [<span class="pl-s">'b'</span>,<span class="pl-s">'d'</span>,<span class="pl-s">'b'</span>,<span class="pl-s">'a'</span>], <span class="pl-s">'col2'</span>: [<span class="pl-c1">3</span>,<span class="pl-c1">1</span>,<span class="pl-c1">1</span>,<span class="pl-c1">2</span>], <span class="pl-s">'data'</span>:[<span class="pl-s">'one'</span>,<span class="pl-s">'two'</span>,<span class="pl-s">'three'</span>,<span class="pl-s">'four'</span>]})

<span class="pl-v">In</span> [<span class="pl-c1">121</span>]: <span class="pl-s1">df2</span> <span class="pl-c1">=</span> <span class="pl-s1">df</span>.<span class="pl-en">set_index</span>([<span class="pl-s">'col1'</span>,<span class="pl-s">'col2'</span>])

<span class="pl-v">In</span> [<span class="pl-c1">122</span>]: <span class="pl-s1">df2</span>.<span class="pl-s1">index</span>.<span class="pl-en">set_levels</span>([<span class="pl-s">'b'</span>,<span class="pl-s">'d'</span>,<span class="pl-s">'a'</span>], <span class="pl-s1">level</span><span class="pl-c1">=</span><span class="pl-s">'col1'</span>, <span class="pl-s1">inplace</span><span class="pl-c1">=</span><span class="pl-c1">True</span>)

<span class="pl-v">In</span> [<span class="pl-c1">123</span>]: <span class="pl-s1">df2</span>.<span class="pl-s1">index</span>.<span class="pl-en">set_labels</span>([<span class="pl-c1">0</span>,<span class="pl-c1">1</span>,<span class="pl-c1">0</span>,<span class="pl-c1">2</span>], <span class="pl-s1">level</span><span class="pl-c1">=</span><span class="pl-s">'col1'</span>, <span class="pl-s1">inplace</span><span class="pl-c1">=</span><span class="pl-c1">True</span>)

<span class="pl-v">In</span> [<span class="pl-c1">124</span>]: <span class="pl-s1">df2</span>.<span class="pl-en">sortlevel</span>()
<span class="pl-v">Out</span>[<span class="pl-c1">124</span>]:
            <span class="pl-s1">data</span>
<span class="pl-s1">col1</span> <span class="pl-s1">col2</span>
<span class="pl-s1">b</span>    <span class="pl-c1">1</span>     <span class="pl-s1">three</span>
     <span class="pl-c1">3</span>       <span class="pl-s1">one</span>
<span class="pl-s1">d</span>    <span class="pl-c1">1</span>       <span class="pl-s1">two</span>
<span class="pl-s1">a</span>    <span class="pl-c1">2</span>      <span class="pl-s1">four</span>

<span class="pl-v">In</span> [<span class="pl-c1">125</span>]: <span class="pl-s1">df2</span>.<span class="pl-en">sort_index</span>()
<span class="pl-v">Out</span>[<span class="pl-c1">125</span>]:
            <span class="pl-s1">data</span>
<span class="pl-s1">col1</span> <span class="pl-s1">col2</span>
<span class="pl-s1">a</span>    <span class="pl-c1">2</span>      <span class="pl-s1">four</span>
<span class="pl-s1">b</span>    <span class="pl-c1">1</span>     <span class="pl-s1">three</span>
     <span class="pl-c1">3</span>       <span class="pl-s1">one</span>
<span class="pl-s1">d</span>    <span class="pl-c1">1</span>       <span class="pl-s1">two</span>

<span class="pl-v">In</span> [<span class="pl-c1">126</span>]: <span class="pl-s1">df2</span>.<span class="pl-en">sort_index</span>(<span class="pl-s1">level</span><span class="pl-c1">=</span><span class="pl-c1">0</span>)
<span class="pl-v">Out</span>[<span class="pl-c1">126</span>]:
            <span class="pl-s1">data</span>
<span class="pl-s1">col1</span> <span class="pl-s1">col2</span>
<span class="pl-s1">b</span>    <span class="pl-c1">1</span>     <span class="pl-s1">three</span>
     <span class="pl-c1">3</span>       <span class="pl-s1">one</span>
<span class="pl-s1">d</span>    <span class="pl-c1">1</span>       <span class="pl-s1">two</span>
<span class="pl-s1">a</span>    <span class="pl-c1">2</span>      <span class="pl-s1">four</span></pre></div>
<p dir="auto">While <code class="notranslate">df2.sort_index()</code> does give a visually lexicographically sorted output, it DOES NOT support slicing.</p>
<div class="highlight highlight-source-python notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="df2.sort_index().loc['b':'d']
---------------------------------------------------------------------------
KeyError                                  Traceback (most recent call last)

# a lot of lines omitted here.

/Users/yimengzh/miniconda/envs/cafferc3/lib/python2.7/site-packages/pandas/indexes/multi.py in _partial_tup_index(self, tup, side)
   1488             raise KeyError('Key length (%d) was greater than MultiIndex'
   1489                            ' lexsort depth (%d)' %
-&gt; 1490                            (len(tup), self.lexsort_depth))
   1491
   1492         n = len(tup)

KeyError: 'Key length (1) was greater than MultiIndex lexsort depth (0)'"><pre class="notranslate"><span class="pl-s1">df2</span>.<span class="pl-en">sort_index</span>().<span class="pl-s1">loc</span>[<span class="pl-s">'b'</span>:<span class="pl-s">'d'</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">-</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">-</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">-</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">-</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">-</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">-</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">-</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">-</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">-</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">-</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">-</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">-</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">-</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">-</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">-</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-c"># a lot of lines omitted here.</span>

<span class="pl-c1">/</span><span class="pl-v">Users</span><span class="pl-c1">/</span><span class="pl-s1">yimengzh</span><span class="pl-c1">/</span><span class="pl-s1">miniconda</span><span class="pl-c1">/</span><span class="pl-s1">envs</span><span class="pl-c1">/</span><span class="pl-s1">cafferc3</span><span class="pl-c1">/</span><span class="pl-s1">lib</span><span class="pl-c1">/</span><span class="pl-s1">python2</span>.<span class="pl-c1">7</span><span class="pl-c1">/</span><span class="pl-s1">site</span><span class="pl-c1">-</span><span class="pl-s1">packages</span><span class="pl-c1">/</span><span class="pl-s1">pandas</span><span class="pl-c1">/</span><span class="pl-s1">indexes</span><span class="pl-c1">/</span><span class="pl-s1">multi</span>.<span class="pl-s1">py</span> <span class="pl-c1">in</span> <span class="pl-en">_partial_tup_index</span>(<span class="pl-s1">self</span>, <span class="pl-s1">tup</span>, <span class="pl-s1">side</span>)
   <span class="pl-c1">1488</span>             <span class="pl-k">raise</span> <span class="pl-v">KeyError</span>(<span class="pl-s">'Key length (%d) was greater than MultiIndex'</span>
   <span class="pl-c1">1489</span>                            <span class="pl-s">' lexsort depth (%d)'</span> <span class="pl-c1">%</span>
<span class="pl-c1">-</span><span class="pl-c1">&gt;</span> <span class="pl-c1">1490</span>                            (<span class="pl-en">len</span>(<span class="pl-s1">tup</span>), <span class="pl-s1">self</span>.<span class="pl-s1">lexsort_depth</span>))
   <span class="pl-c1">1491</span>
   <span class="pl-c1">1492</span>         <span class="pl-s1">n</span> <span class="pl-c1">=</span> <span class="pl-en">len</span>(<span class="pl-s1">tup</span>)

<span class="pl-v">KeyError</span>: <span class="pl-s">'Key length (1) was greater than MultiIndex lexsort depth (0)'</span></pre></div>
<p dir="auto">So I have two questions.</p>
<ol dir="auto">
<li>Is this the intended behavior? I thought <code class="notranslate">level=0</code> and <code class="notranslate">level=None</code> are synonyms to me, but they are not. Looking at the code, <a href="https://github.com/pydata/pandas/blob/4de83d25d751d8ca102867b2d46a5547c01d7248/pandas/core/frame.py#L3245-L3247">https://github.com/pydata/pandas/blob/4de83d25d751d8ca102867b2d46a5547c01d7248/pandas/core/frame.py#L3245-L3247</a> indeed there's a special processing when <code class="notranslate">level</code> is not <code class="notranslate">None</code>.</li>
<li>What does "lexicographically sorted" mean? I think it should mean sorted in terms of levels, not labels. Is this what "lexicographically sorted" means in the doc for Advanced Indexing? If this is true, then I think <code class="notranslate">make_index(level=0)</code> is correct, yet <code class="notranslate">make_index()</code> is not.</li>
</ol>
<p dir="auto">Thanks.</p>
<h4 dir="auto">output of <code class="notranslate">pd.show_versions()</code></h4>
<div class="highlight highlight-source-python notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="In [130]: pd.show_versions()

INSTALLED VERSIONS
------------------
commit: None
python: 2.7.11.final.0
python-bits: 64
OS: Darwin
OS-release: 14.5.0
machine: x86_64
processor: i386
byteorder: little
LC_ALL: None
LANG: en_US.UTF-8

pandas: 0.18.1
nose: 1.3.7
pip: 8.1.2
setuptools: 23.0.0
Cython: 0.23.4
numpy: 1.11.0
scipy: 0.17.0
statsmodels: None
xarray: None
IPython: 4.2.0
sphinx: None
patsy: None
dateutil: 2.5.3
pytz: 2016.4
blosc: None
bottleneck: None
tables: None
numexpr: None
matplotlib: 1.5.1
openpyxl: None
xlrd: None
xlwt: None
xlsxwriter: None
lxml: None
bs4: None
html5lib: None
httplib2: None
apiclient: None
sqlalchemy: None
pymysql: None
psycopg2: None
jinja2: 2.8
boto: None
pandas_datareader: None"><pre class="notranslate"><span class="pl-v">In</span> [<span class="pl-c1">130</span>]: <span class="pl-s1">pd</span>.<span class="pl-en">show_versions</span>()

<span class="pl-v">INSTALLED</span> <span class="pl-v">VERSIONS</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">-</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">-</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">-</span><span class="pl-c1">-</span><span class="pl-c1">-</span><span class="pl-c1">-</span>
<span class="pl-s1">commit</span>: <span class="pl-c1">None</span>
<span class="pl-s1">python</span>: <span class="pl-c1">2.7</span>.<span class="pl-c1">11.</span><span class="pl-s1">final</span>.<span class="pl-c1">0</span>
<span class="pl-s1">python</span><span class="pl-c1">-</span><span class="pl-s1">bits</span>: <span class="pl-c1">64</span>
<span class="pl-v">OS</span>: <span class="pl-v">Darwin</span>
<span class="pl-v">OS</span><span class="pl-c1">-</span><span class="pl-s1">release</span>: <span class="pl-c1">14.5</span><span class="pl-c1">.0</span>
<span class="pl-s1">machine</span>: <span class="pl-s1">x86_64</span>
<span class="pl-s1">processor</span>: <span class="pl-s1">i386</span>
<span class="pl-s1">byteorder</span>: <span class="pl-s1">little</span>
<span class="pl-v">LC_ALL</span>: <span class="pl-c1">None</span>
<span class="pl-v">LANG</span>: <span class="pl-s1">en_US</span>.<span class="pl-v">UTF</span><span class="pl-c1">-</span><span class="pl-c1">8</span>

<span class="pl-s1">pandas</span>: <span class="pl-c1">0.18</span>.<span class="pl-c1">1</span>
<span class="pl-s1">nose</span>: <span class="pl-c1">1.3</span>.<span class="pl-c1">7</span>
<span class="pl-s1">pip</span>: <span class="pl-c1">8.1</span>.<span class="pl-c1">2</span>
<span class="pl-s1">setuptools</span>: <span class="pl-c1">23.0</span>.<span class="pl-c1">0</span>
<span class="pl-v">Cython</span>: <span class="pl-c1">0.23</span>.<span class="pl-c1">4</span>
<span class="pl-s1">numpy</span>: <span class="pl-c1">1.11</span>.<span class="pl-c1">0</span>
<span class="pl-s1">scipy</span>: <span class="pl-c1">0.17</span>.<span class="pl-c1">0</span>
<span class="pl-s1">statsmodels</span>: <span class="pl-c1">None</span>
<span class="pl-s1">xarray</span>: <span class="pl-c1">None</span>
<span class="pl-v">IPython</span>: <span class="pl-c1">4.2</span>.<span class="pl-c1">0</span>
<span class="pl-s1">sphinx</span>: <span class="pl-c1">None</span>
<span class="pl-s1">patsy</span>: <span class="pl-c1">None</span>
<span class="pl-s1">dateutil</span>: <span class="pl-c1">2.5</span>.<span class="pl-c1">3</span>
<span class="pl-s1">pytz</span>: <span class="pl-c1">2016.4</span>
<span class="pl-s1">blosc</span>: <span class="pl-c1">None</span>
<span class="pl-s1">bottleneck</span>: <span class="pl-c1">None</span>
<span class="pl-s1">tables</span>: <span class="pl-c1">None</span>
<span class="pl-s1">numexpr</span>: <span class="pl-c1">None</span>
<span class="pl-s1">matplotlib</span>: <span class="pl-c1">1.5</span>.<span class="pl-c1">1</span>
<span class="pl-s1">openpyxl</span>: <span class="pl-c1">None</span>
<span class="pl-s1">xlrd</span>: <span class="pl-c1">None</span>
<span class="pl-s1">xlwt</span>: <span class="pl-c1">None</span>
<span class="pl-s1">xlsxwriter</span>: <span class="pl-c1">None</span>
<span class="pl-s1">lxml</span>: <span class="pl-c1">None</span>
<span class="pl-s1">bs4</span>: <span class="pl-c1">None</span>
<span class="pl-s1">html5lib</span>: <span class="pl-c1">None</span>
<span class="pl-s1">httplib2</span>: <span class="pl-c1">None</span>
<span class="pl-s1">apiclient</span>: <span class="pl-c1">None</span>
<span class="pl-s1">sqlalchemy</span>: <span class="pl-c1">None</span>
<span class="pl-s1">pymysql</span>: <span class="pl-c1">None</span>
<span class="pl-s1">psycopg2</span>: <span class="pl-c1">None</span>
<span class="pl-s1">jinja2</span>: <span class="pl-c1">2.8</span>
<span class="pl-s1">boto</span>: <span class="pl-c1">None</span>
<span class="pl-s1">pandas_datareader</span>: <span class="pl-c1">None</span></pre></div>