Skip to content

Commit 8161c85

Browse files
committed
Merge pull request #6861 from jreback/inplace
API: add inplace keyword to Series.order/sort to make them inverses (GH6859)
2 parents 31ab9ce + 15c3b9f commit 8161c85

File tree

5 files changed

+71
-46
lines changed

5 files changed

+71
-46
lines changed

doc/source/release.rst

+1
Original file line numberDiff line numberDiff line change
@@ -170,6 +170,7 @@ API Changes
170170
add ``na_position`` arg to conform to ``Series.order`` (:issue:`6847`)
171171
- default sorting algorithm for ``Series.order`` is not ``quicksort``, to conform with ``Series.sort``
172172
(and numpy defaults)
173+
- add ``inplace`` keyword to ``Series.order/sort`` to make them inverses (:issue:`6859`)
173174

174175
Deprecations
175176
~~~~~~~~~~~~

doc/source/v0.14.0.txt

+1
Original file line numberDiff line numberDiff line change
@@ -212,6 +212,7 @@ API changes
212212
add ``na_position`` arg to conform to ``Series.order`` (:issue:`6847`)
213213
- default sorting algorithm for ``Series.order`` is not ``quicksort``, to conform with ``Series.sort``
214214
(and numpy defaults)
215+
- add ``inplace`` keyword to ``Series.order/sort`` to make them inverses (:issue:`6859`)
215216

216217
.. _whatsnew_0140.sql:
217218

pandas/core/series.py

+46-37
Original file line numberDiff line numberDiff line change
@@ -1563,39 +1563,6 @@ def update(self, other):
15631563
#----------------------------------------------------------------------
15641564
# Reindexing, sorting
15651565

1566-
def sort(self, axis=0, ascending=True, kind='quicksort', na_position='last'):
1567-
"""
1568-
Sort values and index labels by value, in place. For compatibility with
1569-
ndarray API. No return value
1570-
1571-
Parameters
1572-
----------
1573-
axis : int (can only be zero)
1574-
ascending : boolean, default True
1575-
Sort ascending. Passing False sorts descending
1576-
kind : {'mergesort', 'quicksort', 'heapsort'}, default 'quicksort'
1577-
Choice of sorting algorithm. See np.sort for more
1578-
information. 'mergesort' is the only stable algorithm
1579-
na_position : {'first', 'last'} (optional, default='last')
1580-
'first' puts NaNs at the beginning
1581-
'last' puts NaNs at the end
1582-
1583-
See Also
1584-
--------
1585-
Series.order
1586-
"""
1587-
1588-
# GH 5856/5863
1589-
if self._is_cached:
1590-
raise ValueError("This Series is a view of some other array, to "
1591-
"sort in-place you must create a copy")
1592-
1593-
result = self.order(ascending=ascending,
1594-
kind=kind,
1595-
na_position=na_position)
1596-
1597-
self._update_inplace(result)
1598-
15991566
def sort_index(self, ascending=True):
16001567
"""
16011568
Sort object by labels (along an axis)
@@ -1692,9 +1659,38 @@ def rank(self, method='average', na_option='keep', ascending=True,
16921659
ascending=ascending, pct=pct)
16931660
return self._constructor(ranks, index=self.index).__finalize__(self)
16941661

1695-
def order(self, na_last=None, ascending=True, kind='quicksort', na_position='last'):
1662+
def sort(self, axis=0, ascending=True, kind='quicksort', na_position='last', inplace=True):
16961663
"""
1697-
Sorts Series object, by value, maintaining index-value link
1664+
Sort values and index labels by value. This is an inplace sort by default.
1665+
Series.order is the equivalent but returns a new Series.
1666+
1667+
Parameters
1668+
----------
1669+
axis : int (can only be zero)
1670+
ascending : boolean, default True
1671+
Sort ascending. Passing False sorts descending
1672+
kind : {'mergesort', 'quicksort', 'heapsort'}, default 'quicksort'
1673+
Choice of sorting algorithm. See np.sort for more
1674+
information. 'mergesort' is the only stable algorithm
1675+
na_position : {'first', 'last'} (optional, default='last')
1676+
'first' puts NaNs at the beginning
1677+
'last' puts NaNs at the end
1678+
inplace : boolean, default True
1679+
Do operation in place.
1680+
1681+
See Also
1682+
--------
1683+
Series.order
1684+
"""
1685+
return self.order(ascending=ascending,
1686+
kind=kind,
1687+
na_position=na_position,
1688+
inplace=inplace)
1689+
1690+
def order(self, na_last=None, ascending=True, kind='quicksort', na_position='last', inplace=False):
1691+
"""
1692+
Sorts Series object, by value, maintaining index-value link.
1693+
This will return a new Series by default. Series.sort is the equivalent but as an inplace method.
16981694
16991695
Parameters
17001696
----------
@@ -1708,6 +1704,8 @@ def order(self, na_last=None, ascending=True, kind='quicksort', na_position='las
17081704
na_position : {'first', 'last'} (optional, default='last')
17091705
'first' puts NaNs at the beginning
17101706
'last' puts NaNs at the end
1707+
inplace : boolean, default False
1708+
Do operation in place.
17111709
17121710
Returns
17131711
-------
@@ -1717,6 +1715,12 @@ def order(self, na_last=None, ascending=True, kind='quicksort', na_position='las
17171715
--------
17181716
Series.sort
17191717
"""
1718+
1719+
# GH 5856/5853
1720+
if inplace and self._is_cached:
1721+
raise ValueError("This Series is a view of some other array, to "
1722+
"sort in-place you must create a copy")
1723+
17201724
if na_last is not None:
17211725
warnings.warn(("na_last is deprecated. Please use na_position instead"),
17221726
FutureWarning)
@@ -1755,8 +1759,13 @@ def _try_kind_sort(arr):
17551759
sortedIdx[:n] = idx[bad]
17561760
else:
17571761
raise ValueError('invalid na_position: {!r}'.format(na_position))
1758-
return self._constructor(arr[sortedIdx], index=self.index[sortedIdx])\
1759-
.__finalize__(self)
1762+
1763+
result = self._constructor(arr[sortedIdx], index=self.index[sortedIdx])
1764+
1765+
if inplace:
1766+
self._update_inplace(result)
1767+
else:
1768+
return result.__finalize__(self)
17601769

17611770
def sortlevel(self, level=0, ascending=True):
17621771
"""

pandas/tests/test_indexing.py

-8
Original file line numberDiff line numberDiff line change
@@ -2849,14 +2849,6 @@ def f():
28492849
zed['eyes']['right'].fillna(value=555, inplace=True)
28502850
self.assertRaises(com.SettingWithCopyError, f)
28512851

2852-
# GH 5856/5863
2853-
# Series.sort operating on a view
2854-
df = DataFrame(np.random.randn(10,4))
2855-
s = df.iloc[:,0]
2856-
def f():
2857-
s.sort()
2858-
self.assertRaises(ValueError, f)
2859-
28602852
df = DataFrame(np.random.randn(10,4))
28612853
s = df.iloc[:,0]
28622854
s = s.order()

pandas/tests/test_series.py

+23-1
Original file line numberDiff line numberDiff line change
@@ -3830,7 +3830,7 @@ def test_dot(self):
38303830
self.assertRaises(ValueError, a.dot, b.T)
38313831

38323832
def test_value_counts_nunique(self):
3833-
3833+
38343834
# basics.rst doc example
38353835
series = Series(np.random.randn(500))
38363836
series[20:500] = np.nan
@@ -3916,6 +3916,28 @@ def test_sort(self):
39163916
self.assert_numpy_array_equal(ts.index,
39173917
self.ts.order(ascending=False).index)
39183918

3919+
# GH 5856/5853
3920+
# Series.sort operating on a view
3921+
df = DataFrame(np.random.randn(10,4))
3922+
s = df.iloc[:,0]
3923+
def f():
3924+
s.sort()
3925+
self.assertRaises(ValueError, f)
3926+
3927+
# test order/sort inplace
3928+
# GH6859
3929+
ts1 = self.ts.copy()
3930+
ts1.sort(ascending=False)
3931+
ts2 = self.ts.copy()
3932+
ts2.order(ascending=False,inplace=True)
3933+
assert_series_equal(ts1,ts2)
3934+
3935+
ts1 = self.ts.copy()
3936+
ts1 = ts1.sort(ascending=False,inplace=False)
3937+
ts2 = self.ts.copy()
3938+
ts2 = ts.order(ascending=False)
3939+
assert_series_equal(ts1,ts2)
3940+
39193941
def test_sort_index(self):
39203942
import random
39213943

0 commit comments

Comments
 (0)