@@ -166,6 +166,7 @@ def take_1d(
166166 indexer : npt .NDArray [np .intp ],
167167 fill_value = None ,
168168 allow_fill : bool = True ,
169+ mask : npt .NDArray [np .bool_ ] | None = None ,
169170) -> ArrayLike :
170171 """
171172 Specialized version for 1D arrays. Differences compared to `take_nd`:
@@ -178,6 +179,22 @@ def take_1d(
178179
179180 Note: similarly to `take_nd`, this function assumes that the indexer is
180181 a valid(ated) indexer with no out of bound indices.
182+
183+ Parameters
184+ ----------
185+ arr : np.ndarray or ExtensionArray
186+ Input array.
187+ indexer : ndarray
188+ 1-D array of indices to take (validated indices, intp dtype).
189+ fill_value : any, default np.nan
190+ Fill value to replace -1 values with
191+ allow_fill : bool, default True
192+ If False, indexer is assumed to contain no -1 values so no filling
193+ will be done. This short-circuits computation of a mask. Result is
194+ undefined if allow_fill == False and -1 is present in indexer.
195+ mask : np.ndarray, optional, default None
196+ If `allow_fill` is True, and the mask (where indexer == -1) is already
197+ known, it can be passed to avoid recomputation.
181198 """
182199 if not isinstance (arr , np .ndarray ):
183200 # ExtensionArray -> dispatch to their method
@@ -187,7 +204,7 @@ def take_1d(
187204 return arr .take (indexer )
188205
189206 dtype , fill_value , mask_info = _take_preprocess_indexer_and_fill_value (
190- arr , indexer , fill_value , True
207+ arr , indexer , fill_value , True , mask
191208 )
192209
193210 # at this point, it's guaranteed that dtype can hold both the arr values
@@ -533,8 +550,9 @@ def _take_preprocess_indexer_and_fill_value(
533550 indexer : npt .NDArray [np .intp ],
534551 fill_value ,
535552 allow_fill : bool ,
553+ mask : npt .NDArray [np .bool_ ] | None = None ,
536554):
537- mask_info = None
555+ mask_info : tuple [ np . ndarray | None , bool ] | None = None
538556
539557 if not allow_fill :
540558 dtype , fill_value = arr .dtype , arr .dtype .type ()
@@ -545,8 +563,11 @@ def _take_preprocess_indexer_and_fill_value(
545563 dtype , fill_value = maybe_promote (arr .dtype , fill_value )
546564 if dtype != arr .dtype :
547565 # check if promotion is actually required based on indexer
548- mask = indexer == - 1
549- needs_masking = mask .any ()
566+ if mask is not None :
567+ needs_masking = True
568+ else :
569+ mask = indexer == - 1
570+ needs_masking = bool (mask .any ())
550571 mask_info = mask , needs_masking
551572 if not needs_masking :
552573 # if not, then depromote, set fill_value to dummy
0 commit comments