From 8d952a1d44bfdb0637e925231bf55edcb944849d Mon Sep 17 00:00:00 2001 From: jreback Date: Wed, 23 Jan 2013 11:07:59 -0500 Subject: [PATCH] ENH: provide squeeze method for removing 1-len dimensions, close (GH #2544) --- RELEASE.rst | 13 +++++++++++++ doc/source/dsintro.rst | 12 ++++++++++++ doc/source/v0.10.2.txt | 29 +++++++++++++++++++++++++++++ doc/source/whatsnew.rst | 2 ++ pandas/core/generic.py | 7 +++++++ pandas/tests/test_ndframe.py | 27 +++++++++++++++++++++++++++ 6 files changed, 90 insertions(+) create mode 100644 doc/source/v0.10.2.txt diff --git a/RELEASE.rst b/RELEASE.rst index 981fa5bed257d..e4b69488ffe9a 100644 --- a/RELEASE.rst +++ b/RELEASE.rst @@ -22,6 +22,19 @@ Where to get it * Binary installers on PyPI: http://pypi.python.org/pypi/pandas * Documentation: http://pandas.pydata.org +**New features** + + - added ``squeeze`` method that will reduce dimensionality of the object by squeezing any len-1 dimensions + +pandas 0.10.2 +============= + +**Release date:** 2013-02-?? + +**New features** + + - Add ``squeeze`` function to reduce dimensionality of 1-len objects + pandas 0.10.1 ============= diff --git a/doc/source/dsintro.rst b/doc/source/dsintro.rst index 362ef8ef7d7fb..64c0fe2c54ac1 100644 --- a/doc/source/dsintro.rst +++ b/doc/source/dsintro.rst @@ -819,6 +819,17 @@ For example, using the earlier example data, we could do: wp.minor_axis wp.minor_xs('C') +Squeezing +~~~~~~~~~ + +Another way to change the dimensionality of an object is to ``squeeze`` a 1-len object, similar to ``wp['Item1']`` + +.. ipython:: python + + wp.reindex(items=['Item1']).squeeze() + wp.reindex(items=['Item1'],minor=['B']).squeeze() + + Conversion to DataFrame ~~~~~~~~~~~~~~~~~~~~~~~ @@ -834,6 +845,7 @@ method: minor_axis=['a', 'b', 'c', 'd']) panel.to_frame() + Panel4D (Experimental) ---------------------- diff --git a/doc/source/v0.10.2.txt b/doc/source/v0.10.2.txt new file mode 100644 index 0000000000000..6e044ef243f2d --- /dev/null +++ b/doc/source/v0.10.2.txt @@ -0,0 +1,29 @@ +.. _whatsnew_0102: + +v0.10.2 (February ??, 2013) +--------------------------- + +This is a minor release from 0.10.1 and includes many new features and +enhancements along with a large number of bug fixes. There are also a number of +important API changes that long-time pandas users should pay close attention +to. + +New features +~~~~~~~~~~~~ + +``Squeeze`` to possibly remove length 1 dimensions from an object. + +.. ipython:: python + + p = Panel(randn(3,4,4),items=['ItemA','ItemB','ItemC'], + major_axis=date_range('20010102',periods=4), + minor_axis=['A','B','C','D']) + p + p.reindex(items=['ItemA']).squeeze() + p.reindex(items=['ItemA'],minor=['B']).squeeze() + + +See the `full release notes +`__ or issue tracker +on GitHub for a complete list. + diff --git a/doc/source/whatsnew.rst b/doc/source/whatsnew.rst index 6c125c45a2599..646610ecccd88 100644 --- a/doc/source/whatsnew.rst +++ b/doc/source/whatsnew.rst @@ -16,6 +16,8 @@ What's New These are new features and improvements of note in each release. +.. include:: v0.10.2.txt + .. include:: v0.10.1.txt .. include:: v0.10.0.txt diff --git a/pandas/core/generic.py b/pandas/core/generic.py index 69bde62fdae20..d2a50c086ab14 100644 --- a/pandas/core/generic.py +++ b/pandas/core/generic.py @@ -587,6 +587,13 @@ def pop(self, item): del self[item] return result + def squeeze(self): + """ squeeze length 1 dimensions """ + try: + return self.ix[tuple([ slice(None) if len(a) > 1 else a[0] for a in self.axes ])] + except: + return self + def _expand_axes(self, key): new_axes = [] for k, ax in zip(key, self.axes): diff --git a/pandas/tests/test_ndframe.py b/pandas/tests/test_ndframe.py index e017bf07039d7..2e82e43c063c1 100644 --- a/pandas/tests/test_ndframe.py +++ b/pandas/tests/test_ndframe.py @@ -26,6 +26,33 @@ def test_astype(self): casted = self.ndf.astype(int) self.assert_(casted.values.dtype == np.int64) + def test_squeeze(self): + # noop + for s in [ t.makeFloatSeries(), t.makeStringSeries(), t.makeObjectSeries() ]: + t.assert_series_equal(s.squeeze(),s) + for df in [ t.makeTimeDataFrame() ]: + t.assert_frame_equal(df.squeeze(),df) + for p in [ t.makePanel() ]: + t.assert_panel_equal(p.squeeze(),p) + for p4d in [ t.makePanel4D() ]: + t.assert_panel4d_equal(p4d.squeeze(),p4d) + + # squeezing + df = t.makeTimeDataFrame().reindex(columns=['A']) + t.assert_series_equal(df.squeeze(),df['A']) + + p = t.makePanel().reindex(items=['ItemA']) + t.assert_frame_equal(p.squeeze(),p['ItemA']) + + p = t.makePanel().reindex(items=['ItemA'],minor_axis=['A']) + t.assert_series_equal(p.squeeze(),p.ix['ItemA',:,'A']) + + p4d = t.makePanel4D().reindex(labels=['label1']) + t.assert_panel_equal(p4d.squeeze(),p4d['label1']) + + p4d = t.makePanel4D().reindex(labels=['label1'],items=['ItemA']) + t.assert_frame_equal(p4d.squeeze(),p4d.ix['label1','ItemA']) + if __name__ == '__main__': import nose nose.runmodule(argv=[__file__, '-vvs', '-x', '--pdb', '--pdb-failure'],