Skip to content

Commit

Permalink
API: add inplace keyword to Series.order/sort to make them inverses (…
Browse files Browse the repository at this point in the history
…GH6859)
  • Loading branch information
jreback committed Apr 10, 2014
1 parent 8438e86 commit 15c3b9f
Show file tree
Hide file tree
Showing 5 changed files with 71 additions and 46 deletions.
1 change: 1 addition & 0 deletions doc/source/release.rst
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,7 @@ API Changes
add ``na_position`` arg to conform to ``Series.order`` (:issue:`6847`)
- default sorting algorithm for ``Series.order`` is not ``quicksort``, to conform with ``Series.sort``
(and numpy defaults)
- add ``inplace`` keyword to ``Series.order/sort`` to make them inverses (:issue:`6859`)

Deprecations
~~~~~~~~~~~~
Expand Down
1 change: 1 addition & 0 deletions doc/source/v0.14.0.txt
Original file line number Diff line number Diff line change
Expand Up @@ -212,6 +212,7 @@ API changes
add ``na_position`` arg to conform to ``Series.order`` (:issue:`6847`)
- default sorting algorithm for ``Series.order`` is not ``quicksort``, to conform with ``Series.sort``
(and numpy defaults)
- add ``inplace`` keyword to ``Series.order/sort`` to make them inverses (:issue:`6859`)

.. _whatsnew_0140.sql:

Expand Down
83 changes: 46 additions & 37 deletions pandas/core/series.py
Original file line number Diff line number Diff line change
Expand Up @@ -1563,39 +1563,6 @@ def update(self, other):
#----------------------------------------------------------------------
# Reindexing, sorting

def sort(self, axis=0, ascending=True, kind='quicksort', na_position='last'):
"""
Sort values and index labels by value, in place. For compatibility with
ndarray API. No return value
Parameters
----------
axis : int (can only be zero)
ascending : boolean, default True
Sort ascending. Passing False sorts descending
kind : {'mergesort', 'quicksort', 'heapsort'}, default 'quicksort'
Choice of sorting algorithm. See np.sort for more
information. 'mergesort' is the only stable algorithm
na_position : {'first', 'last'} (optional, default='last')
'first' puts NaNs at the beginning
'last' puts NaNs at the end
See Also
--------
Series.order
"""

# GH 5856/5863
if self._is_cached:
raise ValueError("This Series is a view of some other array, to "
"sort in-place you must create a copy")

result = self.order(ascending=ascending,
kind=kind,
na_position=na_position)

self._update_inplace(result)

def sort_index(self, ascending=True):
"""
Sort object by labels (along an axis)
Expand Down Expand Up @@ -1692,9 +1659,38 @@ def rank(self, method='average', na_option='keep', ascending=True,
ascending=ascending, pct=pct)
return self._constructor(ranks, index=self.index).__finalize__(self)

def order(self, na_last=None, ascending=True, kind='quicksort', na_position='last'):
def sort(self, axis=0, ascending=True, kind='quicksort', na_position='last', inplace=True):
"""
Sorts Series object, by value, maintaining index-value link
Sort values and index labels by value. This is an inplace sort by default.
Series.order is the equivalent but returns a new Series.
Parameters
----------
axis : int (can only be zero)
ascending : boolean, default True
Sort ascending. Passing False sorts descending
kind : {'mergesort', 'quicksort', 'heapsort'}, default 'quicksort'
Choice of sorting algorithm. See np.sort for more
information. 'mergesort' is the only stable algorithm
na_position : {'first', 'last'} (optional, default='last')
'first' puts NaNs at the beginning
'last' puts NaNs at the end
inplace : boolean, default True
Do operation in place.
See Also
--------
Series.order
"""
return self.order(ascending=ascending,
kind=kind,
na_position=na_position,
inplace=inplace)

def order(self, na_last=None, ascending=True, kind='quicksort', na_position='last', inplace=False):
"""
Sorts Series object, by value, maintaining index-value link.
This will return a new Series by default. Series.sort is the equivalent but as an inplace method.
Parameters
----------
Expand All @@ -1708,6 +1704,8 @@ def order(self, na_last=None, ascending=True, kind='quicksort', na_position='las
na_position : {'first', 'last'} (optional, default='last')
'first' puts NaNs at the beginning
'last' puts NaNs at the end
inplace : boolean, default False
Do operation in place.
Returns
-------
Expand All @@ -1717,6 +1715,12 @@ def order(self, na_last=None, ascending=True, kind='quicksort', na_position='las
--------
Series.sort
"""

# GH 5856/5853
if inplace and self._is_cached:
raise ValueError("This Series is a view of some other array, to "
"sort in-place you must create a copy")

if na_last is not None:
warnings.warn(("na_last is deprecated. Please use na_position instead"),
FutureWarning)
Expand Down Expand Up @@ -1755,8 +1759,13 @@ def _try_kind_sort(arr):
sortedIdx[:n] = idx[bad]
else:
raise ValueError('invalid na_position: {!r}'.format(na_position))
return self._constructor(arr[sortedIdx], index=self.index[sortedIdx])\
.__finalize__(self)

result = self._constructor(arr[sortedIdx], index=self.index[sortedIdx])

if inplace:
self._update_inplace(result)
else:
return result.__finalize__(self)

def sortlevel(self, level=0, ascending=True):
"""
Expand Down
8 changes: 0 additions & 8 deletions pandas/tests/test_indexing.py
Original file line number Diff line number Diff line change
Expand Up @@ -2848,14 +2848,6 @@ def f():
zed['eyes']['right'].fillna(value=555, inplace=True)
self.assertRaises(com.SettingWithCopyError, f)

# GH 5856/5863
# Series.sort operating on a view
df = DataFrame(np.random.randn(10,4))
s = df.iloc[:,0]
def f():
s.sort()
self.assertRaises(ValueError, f)

df = DataFrame(np.random.randn(10,4))
s = df.iloc[:,0]
s = s.order()
Expand Down
24 changes: 23 additions & 1 deletion pandas/tests/test_series.py
Original file line number Diff line number Diff line change
Expand Up @@ -3825,7 +3825,7 @@ def test_dot(self):
self.assertRaises(ValueError, a.dot, b.T)

def test_value_counts_nunique(self):

# basics.rst doc example
series = Series(np.random.randn(500))
series[20:500] = np.nan
Expand Down Expand Up @@ -3911,6 +3911,28 @@ def test_sort(self):
self.assert_numpy_array_equal(ts.index,
self.ts.order(ascending=False).index)

# GH 5856/5853
# Series.sort operating on a view
df = DataFrame(np.random.randn(10,4))
s = df.iloc[:,0]
def f():
s.sort()
self.assertRaises(ValueError, f)

# test order/sort inplace
# GH6859
ts1 = self.ts.copy()
ts1.sort(ascending=False)
ts2 = self.ts.copy()
ts2.order(ascending=False,inplace=True)
assert_series_equal(ts1,ts2)

ts1 = self.ts.copy()
ts1 = ts1.sort(ascending=False,inplace=False)
ts2 = self.ts.copy()
ts2 = ts.order(ascending=False)
assert_series_equal(ts1,ts2)

def test_sort_index(self):
import random

Expand Down

0 comments on commit 15c3b9f

Please sign in to comment.