diff --git a/doc/source/changes.rst b/doc/source/changes.rst index 6ba7a8623..5bcd82c3c 100644 --- a/doc/source/changes.rst +++ b/doc/source/changes.rst @@ -1,6 +1,14 @@ Change log ########## +Version 0.27 +============ + +In development. + +.. include:: ./changes/version_0_27.rst.inc + + Version 0.26.1 ============== diff --git a/doc/source/changes/version_0_27.rst.inc b/doc/source/changes/version_0_27.rst.inc new file mode 100644 index 000000000..1b83c13c9 --- /dev/null +++ b/doc/source/changes/version_0_27.rst.inc @@ -0,0 +1,36 @@ +New features +------------ + +* added a feature (see the :ref:`miscellaneous section ` for details). + +* added `reverse` argument to methods `indicesofsorted` and `labelsofsorted` to sort values in descending order + instead of ascending (default behavior): + + >>> arr = LArray([[1, 5], [3, 2], [0, 4]], "nat=BE,FR,IT; sex=M,F") + >>> arr + nat\sex M F + BE 1 5 + FR 3 2 + IT 0 4 + >>> arr.indicesofsorted("nat", reverse=True) + nat\sex M F + 0 1 0 + 1 0 2 + 2 2 1 + >>> arr.labelsofsorted("nat", reverse=True) + nat\sex M F + 0 FR BE + 1 BE IT + 2 IT FR + + Closes :issue:`490`. + +Miscellaneous improvements +-------------------------- + +* improved something. + +Fixes +----- + +* fixed something (closes :issue:`1`). diff --git a/larray/core/array.py b/larray/core/array.py index ffb1e8e0f..e264c1f8f 100644 --- a/larray/core/array.py +++ b/larray/core/array.py @@ -3076,7 +3076,7 @@ def indexofmax(self, axis=None): posargmax = renamed_to(indexofmax, 'posargmax') - def labelsofsorted(self, axis=None, kind='quicksort'): + def labelsofsorted(self, axis=None, reverse=False, kind='quicksort'): """Returns the labels that would sort this array. Performs an indirect sort along the given axis using the algorithm specified by the `kind` keyword. It returns @@ -3086,6 +3086,8 @@ def labelsofsorted(self, axis=None, kind='quicksort'): ---------- axis : int or str or Axis, optional Axis along which to sort. This can be omitted if array has only one axis. + reverse : bool, optional + Sort values in descending order. Defaults to False (ascending order). kind : {'quicksort', 'mergesort', 'heapsort'}, optional Sorting algorithm. Defaults to 'quicksort'. @@ -3108,18 +3110,23 @@ def labelsofsorted(self, axis=None, kind='quicksort'): BE M F FR F M IT M F + >>> arr.labelsofsorted(X.sex, reverse=True) + nat\\sex 0 1 + BE F M + FR M F + IT F M """ if axis is None: if self.ndim > 1: - raise ValueError("array has ndim > 1 and no axis specified for argsort") + raise ValueError("array has ndim > 1 and no axis specified for labelsofsorted") axis = self.axes[0] axis = self.axes[axis] - pos = self.indicesofsorted(axis, kind=kind) + pos = self.indicesofsorted(axis, reverse=reverse, kind=kind) return LArray(axis.labels[pos.data], pos.axes) argsort = renamed_to(labelsofsorted, 'argsort') - def indicesofsorted(self, axis=None, kind='quicksort'): + def indicesofsorted(self, axis=None, reverse=False, kind='quicksort'): """Returns the indices that would sort this array. Performs an indirect sort along the given axis using the algorithm specified by the `kind` keyword. It returns @@ -3129,6 +3136,8 @@ def indicesofsorted(self, axis=None, kind='quicksort'): ---------- axis : int or str or Axis, optional Axis along which to sort. This can be omitted if array has only one axis. + reverse : bool, optional + Sort values in descending order. Defaults to False (ascending order). kind : {'quicksort', 'mergesort', 'heapsort'}, optional Sorting algorithm. Defaults to 'quicksort'. @@ -3151,13 +3160,22 @@ def indicesofsorted(self, axis=None, kind='quicksort'): 0 2 1 1 0 2 2 1 0 + >>> arr.indicesofsorted(X.nat, reverse=True) + nat\\sex M F + 0 1 0 + 1 0 2 + 2 2 1 """ if axis is None: if self.ndim > 1: - raise ValueError("array has ndim > 1 and no axis specified for posargsort") + raise ValueError("array has ndim > 1 and no axis specified for indicesofsorted") axis = self.axes[0] axis, axis_idx = self.axes[axis], self.axes.index(axis) data = self.data.argsort(axis_idx, kind=kind) + if reverse: + reverser = tuple(slice(None, None, -1) if i == axis_idx else slice(None) + for i in range(self.ndim)) + data = data[reverser] new_axis = Axis(np.arange(len(axis)), axis.name) return LArray(data, self.axes.replace(axis, new_axis))