Skip to content

Commit e724ade

Browse files
committed
Move resorting to algos
1 parent 97fe91f commit e724ade

File tree

2 files changed

+29
-12
lines changed

2 files changed

+29
-12
lines changed

pandas/core/algorithms.py

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2115,3 +2115,28 @@ def sort_mixed(values):
21152115
np.putmask(new_codes, mask, na_sentinel)
21162116

21172117
return ordered, ensure_platform_int(new_codes)
2118+
2119+
2120+
def resort_union_after_inputs(union_values, lvals, rvals) -> np.ndarray:
2121+
"""
2122+
Elements from union_values are resorted after the order of
2123+
lvals and then rvals, if element is not in lvals. All occurrences
2124+
are placed at the spot of the first occurrence of this element.
2125+
2126+
Parameters
2127+
----------
2128+
union_values: np.array which is a sorted union of lvals and rvals
2129+
lvals: np.ndarray of the left values which is ordered in front.
2130+
rvals: np.ndarray of the right values ordered after lvals.
2131+
2132+
Returns
2133+
-------
2134+
np.ndarray containing the resorted values from union_values
2135+
"""
2136+
indexer = []
2137+
counts = dict(zip(*np.unique(union_values, return_counts=True)))
2138+
unique_array = unique(np.append(lvals, rvals))
2139+
# Create indexer to resort result
2140+
for i, value in enumerate(unique_array):
2141+
indexer += [i] * counts[value]
2142+
return unique_array.take(indexer)

pandas/core/indexes/base.py

Lines changed: 4 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -2659,11 +2659,8 @@ def _union(self, other, sort):
26592659
rvals = other._values
26602660

26612661
try:
2662-
if sort is None and self.is_monotonic and other.is_monotonic:
2663-
result = self._outer_indexer(lvals, rvals)[0]
2664-
else:
2665-
# We calculate the sorted union and resort it afterwards
2666-
result = self._outer_indexer(np.sort(lvals), np.sort(rvals))
2662+
# If one of both is not monotonic, we resort it afterwards
2663+
result = self._outer_indexer(np.sort(lvals), np.sort(rvals))[0]
26672664
except TypeError:
26682665
# incomparable objects
26692666
result = list(lvals)
@@ -2674,13 +2671,8 @@ def _union(self, other, sort):
26742671
result = Index(result)._values # do type inference here
26752672
else:
26762673
if sort is False or not self.is_monotonic or not other.is_monotonic:
2677-
indexer = []
2678-
counts = dict(zip(*np.unique(result[0], return_counts=True)))
2679-
unique_array = algos.unique(np.append(lvals, rvals))
2680-
# Create indexer to resort result
2681-
for i, value in enumerate(unique_array):
2682-
indexer += [i] * counts[value]
2683-
result = unique_array.take(indexer)
2674+
result = algos.resort_union_after_inputs(result, lvals, rvals)
2675+
26842676
if sort is None and (not self.is_monotonic or not other.is_monotonic):
26852677
try:
26862678
result = algos.safe_sort(result)

0 commit comments

Comments
 (0)