<p dir="auto">Passing a list of strings to the DataFrame.sort() method is stable, but passing a string by itself causes the sort to be unstable.</p>
<p dir="auto">I'm defining sort stability to mean row order is maintained for duplicate values in the sorted column.</p>
<h2 dir="auto">Code to recreate</h2>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="&gt;&gt;&gt;import pandas as pd
&gt;&gt;&gt;df = pd.DataFrame(list('ABCDABCDABCD'), columns=['x'])
&gt;&gt;&gt;print df.sort(['x'])
    x
0   A
4   A
8   A
1   B
5   B
9   B
2   C
6   C
10  C
3   D
7   D
11  D
&gt;&gt;&gt;print df.sort('x')
    x
0   A
4   A
8   A
1   B
5   B
9   B
6   C
10  C
2   C
3   D
11  D
7   D"><pre class="notranslate"><code class="notranslate">&gt;&gt;&gt;import pandas as pd
&gt;&gt;&gt;df = pd.DataFrame(list('ABCDABCDABCD'), columns=['x'])
&gt;&gt;&gt;print df.sort(['x'])
    x
0   A
4   A
8   A
1   B
5   B
9   B
2   C
6   C
10  C
3   D
7   D
11  D
&gt;&gt;&gt;print df.sort('x')
    x
0   A
4   A
8   A
1   B
5   B
9   B
6   C
10  C
2   C
3   D
11  D
7   D
</code></pre></div>
<p dir="auto">The index is out of order for C and D in the 2nd case.</p>
<p dir="auto">pandas version 0.10.0<br>
Python version 2.7.2<br>
Windows 7, 64-bit</p>
<p dir="auto">see discussion in <a class="issue-link js-issue-link" data-error-text="Failed to load title" data-id="12049172" data-permission-text="Title is private" data-url="https://github.com/pandas-dev/pandas/issues/3059" data-hovercard-type="pull_request" data-hovercard-url="/pandas-dev/pandas/pull/3059/hovercard" href="https://github.com/pandas-dev/pandas/pull/3059">#3059</a>, <a class="issue-link js-issue-link" data-error-text="Failed to load title" data-id="12196758" data-permission-text="Title is private" data-url="https://github.com/pandas-dev/pandas/issues/3095" data-hovercard-type="issue" data-hovercard-url="/pandas-dev/pandas/issues/3095/hovercard" href="https://github.com/pandas-dev/pandas/issues/3095">#3095</a>, also see <a class="issue-link js-issue-link" data-error-text="Failed to load title" data-id="7013605" data-permission-text="Title is private" data-url="https://github.com/pandas-dev/pandas/issues/1943" data-hovercard-type="issue" data-hovercard-url="/pandas-dev/pandas/issues/1943/hovercard" href="https://github.com/pandas-dev/pandas/issues/1943">#1943</a>, <a class="issue-link js-issue-link" data-error-text="Failed to load title" data-id="12210717" data-permission-text="Title is private" data-url="https://github.com/pandas-dev/pandas/issues/3102" data-hovercard-type="pull_request" data-hovercard-url="/pandas-dev/pandas/pull/3102/hovercard" href="https://github.com/pandas-dev/pandas/pull/3102">#3102</a></p>
<p dir="auto">This only applies with a non-unique column index</p>
<p dir="auto">Currently if duplicate columns across dtypes there are issues in getting the correct block given a column name.</p>
<p dir="auto">I think it is possible, though non-trivial, to instead have a positional map from the frame columns to the BlockManager blocks, will simplify BlockManager.iget.</p>
<p dir="auto">Primary motivation is to_csv currently cannot handle these types of lookups.</p>
<p dir="auto">Also should eliminate need for _find_block</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="In [6]: df = pd.DataFrame(np.random.randn(8,4))

In [12]: df = pd.DataFrame(np.random.randn(8,4))

In [13]: df._data.blocks[0].ref_locs
Out[13]: array([0, 1, 2, 3])

In [14]: df = pd.DataFrame(np.random.randn(8,4),columns=['a']*4)

In [15]: df._data.blocks[0].ref_locs
---------------------------------------------------------------------------

/mnt/home/jreback/pandas/pandas/core/internals.py in ref_locs(self)
     52     def ref_locs(self):
     53         if self._ref_locs is None:
---&gt; 54             indexer = self.ref_items.get_indexer(self.items)
     55             indexer = com._ensure_platform_int(indexer)
     56             if (indexer == -1).any():

/mnt/home/jreback/pandas/pandas/core/index.pyc in get_indexer(self, target, method, limit)
    835 
    836         if not self.is_unique:
--&gt; 837             raise Exception('Reindexing only valid with uniquely valued Index '
    838                             'objects')
    839 

Exception: Reindexing only valid with uniquely valued Index objects"><pre class="notranslate"><code class="notranslate">In [6]: df = pd.DataFrame(np.random.randn(8,4))

In [12]: df = pd.DataFrame(np.random.randn(8,4))

In [13]: df._data.blocks[0].ref_locs
Out[13]: array([0, 1, 2, 3])

In [14]: df = pd.DataFrame(np.random.randn(8,4),columns=['a']*4)

In [15]: df._data.blocks[0].ref_locs
---------------------------------------------------------------------------

/mnt/home/jreback/pandas/pandas/core/internals.py in ref_locs(self)
     52     def ref_locs(self):
     53         if self._ref_locs is None:
---&gt; 54             indexer = self.ref_items.get_indexer(self.items)
     55             indexer = com._ensure_platform_int(indexer)
     56             if (indexer == -1).any():

/mnt/home/jreback/pandas/pandas/core/index.pyc in get_indexer(self, target, method, limit)
    835 
    836         if not self.is_unique:
--&gt; 837             raise Exception('Reindexing only valid with uniquely valued Index '
    838                             'objects')
    839 

Exception: Reindexing only valid with uniquely valued Index objects
</code></pre></div>
<p dir="auto">This is the root of all evil, this should raise the same as above (but doesn't even if<br>
I consolidate)......</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="In [16]: df = pd.DataFrame(np.random.randn(8,4))

In [17]: df.columns = ['a']*4

In [18]: df._data.blocks[0].ref_locs
Out[18]: array([0, 1, 2, 3])"><pre class="notranslate"><code class="notranslate">In [16]: df = pd.DataFrame(np.random.randn(8,4))

In [17]: df.columns = ['a']*4

In [18]: df._data.blocks[0].ref_locs
Out[18]: array([0, 1, 2, 3])
</code></pre></div>