Skip to content

Commit f9d6970

Browse files
committed
PERF: transform single keys without going 2D
1 parent ebc2b4b commit f9d6970

File tree

2 files changed

+21
-13
lines changed

2 files changed

+21
-13
lines changed

pandas/_libs/index.pyx

+2-4
Original file line numberDiff line numberDiff line change
@@ -692,10 +692,8 @@ cdef class BaseMultiIndexCodesEngine:
692692
except KeyError:
693693
raise KeyError(key)
694694

695-
# ndmin=2 because codes_to_ints expects multiple labels:
696-
indices = np.array(indices, ndmin=2, dtype='uint64')
697-
# ... and returns a (length 1, in this case) array of integers:
698-
lab_int = self._codes_to_ints(indices)[0]
695+
# Transform indices into single integer:
696+
lab_int = self._codes_to_ints(np.array(indices, dtype='uint64'))
699697

700698
return self._base.get_loc(self, lab_int)
701699

pandas/core/indexes/multi.py

+19-9
Original file line numberDiff line numberDiff line change
@@ -55,27 +55,32 @@ class MultiIndexUIntEngine(libindex.BaseMultiIndexCodesEngine,
5555

5656
def _codes_to_ints(self, codes):
5757
"""
58-
Transform each row of a 2d array of uint64 in a uint64, in a strictly
58+
Transform combination(s) of uint64 in one uint64 (each), in a strictly
5959
monotonic way (i.e. respecting the lexicographic order of integer
6060
combinations): see BaseMultiIndexCodesEngine documentation.
6161
6262
Parameters
6363
----------
64-
codes : 2-dimensional array of dtype uint64
64+
codes : 1- or 2-dimensional array of dtype uint64
6565
Combinations of integers (one per row)
6666
6767
Returns
6868
------
69-
int_keys : 1-dimensional array of dtype uint64
70-
Integers representing one combination each
69+
int_keys : scalar or 1-dimensional array, of dtype uint64
70+
Integer(s) representing one combination (each)
7171
"""
7272
# Shift the representation of each level by the pre-calculated number
7373
# of bits:
7474
codes <<= self.offsets
7575

7676
# Now sum and OR are in fact interchangeable. This is a simple
7777
# composition of the (disjunct) significant bits of each level (i.e.
78-
# each column in "codes") in a single positive integer (per row):
78+
# each column in "codes") in a single positive integer:
79+
if codes.ndim == 1:
80+
# Single key
81+
return np.bitwise_or.reduce(codes)
82+
83+
# Multiple keys
7984
return np.bitwise_or.reduce(codes, axis=1)
8085

8186

@@ -90,19 +95,19 @@ class MultiIndexPyIntEngine(libindex.BaseMultiIndexCodesEngine,
9095

9196
def _codes_to_ints(self, codes):
9297
"""
93-
Transform each row of a 2d array of uint64 in a Python integer, in a
98+
Transform combination(s) of uint64 in one Python integer (each), in a
9499
strictly monotonic way (i.e. respecting the lexicographic order of
95100
integer combinations): see BaseMultiIndexCodesEngine documentation.
96101
97102
Parameters
98103
----------
99-
codes : 2-dimensional array of dtype uint64
104+
codes : 1- or 2-dimensional array of dtype uint64
100105
Combinations of integers (one per row)
101106
102107
Returns
103108
------
104-
int_keys : 1-dimensional array of dtype object
105-
Integers representing one combination each
109+
int_keys : int, or 1-dimensional array of dtype object
110+
Integer(s) representing one combination (each)
106111
"""
107112

108113
# Shift the representation of each level by the pre-calculated number
@@ -113,6 +118,11 @@ def _codes_to_ints(self, codes):
113118
# Now sum and OR are in fact interchangeable. This is a simple
114119
# composition of the (disjunct) significant bits of each level (i.e.
115120
# each column in "codes") in a single positive integer (per row):
121+
if codes.ndim == 1:
122+
# Single key
123+
return np.bitwise_or.reduce(codes)
124+
125+
# Multiple keys
116126
return np.bitwise_or.reduce(codes, axis=1)
117127

118128

0 commit comments

Comments
 (0)