Skip to content

Commit 3b00019

Browse files
committed
API: Always allow sorted=False and make a note about it
User intent for `sorted=False` is very clear, so I think we can really just allow it. However, note in the docs that it could change. Also add a bigger note in the `unique_*` functions that still always return a sorted result but would change in the future (whenever `sorted=False` does work).
1 parent 2fd2491 commit 3b00019

File tree

2 files changed

+29
-16
lines changed

2 files changed

+29
-16
lines changed

numpy/lib/_arraysetops_impl.py

Lines changed: 18 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -186,7 +186,9 @@ def unique(ar, return_index=False, return_inverse=False,
186186
.. versionadded:: 1.24
187187
188188
sorted : bool, optional
189-
If True, the unique elements are sorted.
189+
If True, the unique elements are sorted. Elements may be sorted in
190+
practice even if ``sorted=False``, but this could change without
191+
notice.
190192
191193
.. versionadded:: 2.3
192194
@@ -361,12 +363,6 @@ def _unique1d(ar, return_index=False, return_inverse=False,
361363

362364
optional_indices = return_index or return_inverse
363365

364-
if (optional_indices or return_counts) and not sorted:
365-
raise ValueError(
366-
"Currently, `sorted` can only be False if `return_index`, "
367-
"`return_inverse`, and `return_counts` are all False."
368-
)
369-
370366
# masked arrays are not supported yet.
371367
if not optional_indices and not return_counts and not np.ma.is_masked(ar):
372368
# First we convert the array to a numpy array, later we wrap it back
@@ -448,10 +444,14 @@ def unique_all(x):
448444
This function is an Array API compatible alternative to::
449445
450446
np.unique(x, return_index=True, return_inverse=True,
451-
return_counts=True, equal_nan=False)
447+
return_counts=True, equal_nan=False, sorted=False)
452448
453449
but returns a namedtuple for easier access to each output.
454450
451+
.. note::
452+
This function currently always returns a sorted result, however,
453+
this could change in any NumPy minor release.
454+
455455
Parameters
456456
----------
457457
x : array_like
@@ -507,10 +507,14 @@ def unique_counts(x):
507507
508508
This function is an Array API compatible alternative to::
509509
510-
np.unique(x, return_counts=True, equal_nan=False)
510+
np.unique(x, return_counts=True, equal_nan=False, sorted=False)
511511
512512
but returns a namedtuple for easier access to each output.
513513
514+
.. note::
515+
This function currently always returns a sorted result, however,
516+
this could change in any NumPy minor release.
517+
514518
Parameters
515519
----------
516520
x : array_like
@@ -559,10 +563,14 @@ def unique_inverse(x):
559563
560564
This function is an Array API compatible alternative to::
561565
562-
np.unique(x, return_inverse=True, equal_nan=False)
566+
np.unique(x, return_inverse=True, equal_nan=False, sorted=False)
563567
564568
but returns a namedtuple for easier access to each output.
565569
570+
.. note::
571+
This function currently always returns a sorted result, however,
572+
this could change in any NumPy minor release.
573+
566574
Parameters
567575
----------
568576
x : array_like

numpy/lib/tests/test_arraysetops.py

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -838,14 +838,19 @@ class Subclass(np.ndarray):
838838

839839
@pytest.mark.parametrize("arg", ["return_index", "return_inverse", "return_counts"])
840840
def test_unsupported_hash_based(self, arg):
841-
"""Test that hash based unique is not supported when either of
842-
return_index, return_inverse, or return_counts is True.
841+
"""These currently never use the hash-based solution. However,
842+
it seems easier to just allow it.
843843
844-
This is WIP and the above will gradually be supported in the future.
844+
When the hash-based solution is added, this test should fail and be
845+
replaced with something more comprehensive.
845846
"""
846-
msg = "Currently, `sorted` can only be False"
847-
with pytest.raises(ValueError, match=msg):
848-
np.unique([1, 1], sorted=False, **{arg: True})
847+
a = np.array([1, 5, 2, 3, 4, 8, 199, 1, 3, 5])
848+
849+
res_not_sorted = np.unique([1, 1], sorted=False, **{arg: True})
850+
res_sorted = np.unique([1, 1], sorted=True, **{arg: True})
851+
# The following should fail without first sorting `res_not_sorted`.
852+
for arr, expected in zip(res_not_sorted, res_sorted):
853+
assert_array_equal(arr, expected)
849854

850855
def test_unique_axis_errors(self):
851856
assert_raises(TypeError, self._run_axis_tests, object)

0 commit comments

Comments
 (0)