Skip to content

Commit aac172c

Browse files
committed
[WIP]: API: Change default for Index.union sort
Closes pandas-dev#24959
1 parent abf0824 commit aac172c

File tree

2 files changed

+77
-6
lines changed

2 files changed

+77
-6
lines changed

pandas/core/indexes/base.py

+31-6
Original file line numberDiff line numberDiff line change
@@ -2245,18 +2245,34 @@ def _get_reconciled_name_object(self, other):
22452245
return self._shallow_copy(name=name)
22462246
return self
22472247

2248-
def union(self, other, sort=True):
2248+
def union(self, other, sort=None):
22492249
"""
22502250
Form the union of two Index objects.
22512251
22522252
Parameters
22532253
----------
22542254
other : Index or array-like
2255-
sort : bool, default True
2256-
Sort the resulting index if possible
2255+
sort : bool or None, default None
2256+
Whether to sort the resulting Index.
2257+
2258+
* None : Sort the result, except when
2259+
2260+
1. `self` and `other` are equal.
2261+
2. `self` or `other` has length 0.
2262+
3. Some values in `self` or `other` cannot be compared.
2263+
A RuntimeWarning is issued in this case.
2264+
2265+
* True : sort the result. A TypeError is raised when the
2266+
values cannot be compared.
2267+
* False : do not sort the result.
22572268
22582269
.. versionadded:: 0.24.0
22592270
2271+
.. versionchanged:: 0.24.0
2272+
2273+
Changed the default `sort` to None, matching the
2274+
behavior of pandas 0.23.4 and earlier.
2275+
22602276
Returns
22612277
-------
22622278
union : Index
@@ -2273,10 +2289,16 @@ def union(self, other, sort=True):
22732289
other = ensure_index(other)
22742290

22752291
if len(other) == 0 or self.equals(other):
2276-
return self._get_reconciled_name_object(other)
2292+
result = self._get_reconciled_name_object(other)
2293+
if sort:
2294+
result = result.sort_values()
2295+
return result
22772296

22782297
if len(self) == 0:
2279-
return other._get_reconciled_name_object(self)
2298+
result = other._get_reconciled_name_object(self)
2299+
if sort:
2300+
result = result.sort_values()
2301+
return result
22802302

22812303
# TODO: is_dtype_union_equal is a hack around
22822304
# 1. buggy set ops with duplicates (GH #13432)
@@ -2319,13 +2341,16 @@ def union(self, other, sort=True):
23192341
else:
23202342
result = lvals
23212343

2322-
if sort:
2344+
if sort is None:
23232345
try:
23242346
result = sorting.safe_sort(result)
23252347
except TypeError as e:
23262348
warnings.warn("{}, sort order is undefined for "
23272349
"incomparable objects".format(e),
23282350
RuntimeWarning, stacklevel=3)
2351+
elif sort:
2352+
# raise if not sortable.
2353+
result = sorting.safe_sort(result)
23292354

23302355
# for subclasses
23312356
return self._wrap_setop_result(other, result)

pandas/tests/indexes/test_base.py

+46
Original file line numberDiff line numberDiff line change
@@ -794,6 +794,52 @@ def test_union(self, sort):
794794
tm.assert_index_equal(union, everything.sort_values())
795795
assert tm.equalContents(union, everything)
796796

797+
def test_union_sort_other_equal(self):
798+
a = pd.Index([1, 0, 2])
799+
# default, sort=None
800+
result = a.union(a)
801+
tm.assert_index_equal(result, a)
802+
803+
# sort=True
804+
result = a.union(a, sort=True)
805+
expected = pd.Index([0, 1, 2])
806+
tm.assert_index_equal(result, expected)
807+
808+
# sort=False
809+
result = a.union(a, sort=False)
810+
tm.assert_index_equal(result, a)
811+
812+
def test_union_sort_other_empty(self):
813+
a = pd.Index([1, 0, 2])
814+
# default, sort=None
815+
tm.assert_index_equal(a.union(a[:0]), a)
816+
tm.assert_index_equal(a[:0].union(a), a)
817+
818+
# sort=True
819+
expected = pd.Index([0, 1, 2])
820+
tm.assert_index_equal(a.union(a[:0], sort=True), expected)
821+
tm.assert_index_equal(a[:0].union(a, sort=True), expected)
822+
823+
# sort=False
824+
tm.assert_index_equal(a.union(a[:0], sort=False), a)
825+
tm.assert_index_equal(a[:0].union(a, sort=False), a)
826+
827+
def test_union_sort_other_incomparable(self):
828+
a = pd.Index([1, pd.Timestamp('2000')])
829+
# default, sort=None
830+
with tm.assert_produces_warning(RuntimeWarning):
831+
result = a.union(a[:1])
832+
833+
tm.assert_index_equal(result, a)
834+
835+
# sort=True
836+
with pytest.raises(TypeError, match='.*'):
837+
a.union(a[:1], sort=True)
838+
839+
# sort=False
840+
result = a.union(a[:1], sort=False)
841+
tm.assert_index_equal(result, a)
842+
797843
@pytest.mark.parametrize("klass", [
798844
np.array, Series, list])
799845
@pytest.mark.parametrize("sort", [True, False])

0 commit comments

Comments
 (0)