Skip to content

Commit 4a8b6e5

Browse files
jbrockmendelJulianWgs
authored andcommitted
PERF: is_bool_indexer (pandas-dev#41861)
1 parent 6959cb5 commit 4a8b6e5

File tree

3 files changed

+43
-2
lines changed

3 files changed

+43
-2
lines changed

pandas/_libs/lib.pyi

+3
Original file line numberDiff line numberDiff line change
@@ -267,3 +267,6 @@ def get_reverse_indexer(
267267
indexer: np.ndarray, # const intp_t[:]
268268
length: int,
269269
) -> np.ndarray: ... # np.ndarray[np.intp]
270+
271+
272+
def is_bool_list(obj: list) -> bool: ...

pandas/_libs/lib.pyx

+38
Original file line numberDiff line numberDiff line change
@@ -2920,3 +2920,41 @@ def to_object_array_tuples(rows: object) -> np.ndarray:
29202920
result[i, j] = row[j]
29212921

29222922
return result
2923+
2924+
2925+
def is_bool_list(obj: list) -> bool:
2926+
"""
2927+
Check if this list contains only bool or np.bool_ objects.
2928+
2929+
This is appreciably faster than checking `np.array(obj).dtype == bool`
2930+
2931+
obj1 = [True, False] * 100
2932+
obj2 = obj1 * 100
2933+
obj3 = obj2 * 100
2934+
obj4 = [True, None] + obj1
2935+
2936+
for obj in [obj1, obj2, obj3, obj4]:
2937+
%timeit is_bool_list(obj)
2938+
%timeit np.array(obj).dtype.kind == "b"
2939+
2940+
340 ns ± 8.22 ns
2941+
8.78 µs ± 253 ns
2942+
2943+
28.8 µs ± 704 ns
2944+
813 µs ± 17.8 µs
2945+
2946+
3.4 ms ± 168 µs
2947+
78.4 ms ± 1.05 ms
2948+
2949+
48.1 ns ± 1.26 ns
2950+
8.1 µs ± 198 ns
2951+
"""
2952+
cdef:
2953+
object item
2954+
2955+
for item in obj:
2956+
if not util.is_bool_object(item):
2957+
return False
2958+
2959+
# Note: we return True for empty list
2960+
return True

pandas/core/common.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -142,8 +142,8 @@ def is_bool_indexer(key: Any) -> bool:
142142
elif is_bool_dtype(key.dtype):
143143
return True
144144
elif isinstance(key, list):
145-
arr = np.asarray(key)
146-
return arr.dtype == np.bool_ and len(arr) == len(key)
145+
# check if np.array(key).dtype would be bool
146+
return len(key) > 0 and lib.is_bool_list(key)
147147

148148
return False
149149

0 commit comments

Comments
 (0)