.. _whatsnew_0140:

v0.14.0 (May ? , 2014)
----------------------

This is a major release from 0.13.1 and includes a small number of API changes, several new features,
enhancements, and performance improvements along with a large number of bug fixes. We recommend that all
users upgrade to this version.

Highlights include:

-


API changes
~~~~~~~~~~~

- ``iloc`` will now accept out-of-bounds indexers, e.g. a value that exceeds the length of the object being
  indexed. These will be excluded. This will make pandas conform more with pandas/numpy indexing of out-of-bounds
  values. A single indexer that is out-of-bounds and drops the dimensions of the object will still raise
  ``IndexError`` (:issue:`6296`). This could result in an empty axis (e.g. an empty DataFrame being returned)

  .. ipython:: python

      df = DataFrame(np.random.randn(5,2),columns=list('AB'))
      df
      df.iloc[[4,5,6]]
      df.iloc[4:6]
      df.iloc[:,2:3]
      df.iloc[:,1:3]

MultiIndexing Using Slicers
~~~~~~~~~~~~~~~~~~~~~~~~~~~

In 0.14.0 we added a new way to slice multi-indexed objects.
You can slice a multi-index by providing multiple indexers.
You can use ``slice(None)`` to select all the contents of *that* level.
You do not need to specify all the *deeper* levels, they will be implied
as ``slice(None)``. As usual, **both sides** of the slicers are included as this is
label indexing.

See :ref:`the docs<indexing.mi_slicers>`
See also issues (:issue:`6134`, :issue:`4036`, :issue:`3057`, :issue:`2598`, :issue:`5641`)

.. warning::

   You should specify all axes in the ``.loc`` specifier, meaning the indexer for the **index** and
   for the **columns**. Their are some ambiguous cases where the passed indexer could be mis-interpreted
   as indexing *both* axes, rather than into say the MuliIndex for the rows.

   You should do this:

   .. code-block:: python

      df.loc[(slice('A1','A3'),.....,:]

   rather than this:

   .. code-block:: python

      df.loc[(slice('A1','A3'),.....]

.. warning::

   You will need to make sure that the selection axes are fully lexsorted!

.. ipython:: python

   def mklbl(prefix,n):
       return ["%s%s" % (prefix,i)  for i in range(n)]

   index = MultiIndex.from_product([mklbl('A',4),
                                    mklbl('B',2),
                                    mklbl('C',4),
                                    mklbl('D',2)])
   columns = MultiIndex.from_tuples([('a','foo'),('a','bar'),
                                     ('b','foo'),('b','bah')],
                                      names=['lvl0', 'lvl1'])
   df = DataFrame(np.arange(len(index)*len(columns)).reshape((len(index),len(columns))),
                  index=index,
                  columns=columns).sortlevel().sortlevel(axis=1)
   df

.. ipython:: python

   df.loc[(slice('A1','A3'),slice(None), ['C1','C3']),:]
   df.loc[(slice(None),slice(None), ['C1','C3']),:]

It is possible to perform quite complicated selections using this method on multiple
axes at the same time.

.. ipython:: python

   df.loc['A1',(slice(None),'foo')]
   df.loc[(slice(None),slice(None), ['C1','C3']),(slice(None),'foo')]

Furthermore you can *set* the values using these methods

.. ipython:: python

   df2 = df.copy()
   df2.loc[(slice(None),slice(None), ['C1','C3']),:] = -10
   df2

You use a right-hand-side of an alignable object as well.

.. ipython:: python

   df2 = df.copy()
   df2.loc[(slice(None),slice(None), ['C1','C3']),:] = df2*1000
   df2

Prior Version Deprecations/Changes
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

There are no announced changes in 0.13.1 or prior that are taking effect as of 0.14.0

Deprecations
~~~~~~~~~~~~

There are no deprecations of prior behavior in 0.14.0

Enhancements
~~~~~~~~~~~~

- pd.read_clipboard will, if 'sep' is unspecified, try to detect data copied from a spreadsheet
  and parse accordingly. (:issue:`6223`)
- ``plot(legend='reverse')`` will now reverse the order of legend labels for
  most plot kinds. (:issue:`6014`)


Performance
~~~~~~~~~~~

Experimental
~~~~~~~~~~~~

There are no experimental changes in 0.14.0

Bug Fixes
~~~~~~~~~

See :ref:`V0.14.0 Bug Fixes<release.bug_fixes-0.14.0>` for an extensive list of bugs that have been fixed in 0.14.0.

See the :ref:`full release notes
<release>` or issue tracker
on GitHub for a complete list of all API changes, Enhancements and Bug Fixes.
