Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 19 additions & 14 deletions pandas/core/algorithms.py
Original file line number Diff line number Diff line change
Expand Up @@ -171,12 +171,12 @@ def _ensure_data(values: ArrayLike) -> np.ndarray:
return np.asarray(values)

elif is_complex_dtype(values.dtype):
return cast(np.ndarray, values)
return cast("np.ndarray", values)

# datetimelike
elif needs_i8_conversion(values.dtype):
npvalues = values.view("i8")
npvalues = cast(np.ndarray, npvalues)
npvalues = cast("np.ndarray", npvalues)
return npvalues

# we have failed, return object
Expand Down Expand Up @@ -1054,21 +1054,28 @@ def rank(
Whether or not to the display the returned rankings in integer form
(e.g. 1, 2, 3) or in percentile form (e.g. 0.333..., 0.666..., 1).
"""
is_datetimelike = needs_i8_conversion(values.dtype)
values = _ensure_data(values)
# Optimization: cache dtype and ndim, early-branch on common case
v_dtype = getattr(values, "dtype", None)
v_ndim = getattr(values, "ndim", None)
is_datetimelike = needs_i8_conversion(v_dtype)
# Inline minimal _ensure_data logic: convert to ndarray if not already
if isinstance(values, np.ndarray):
arr = values
else:
arr = np.asarray(values)

if values.ndim == 1:
ranks = algos.rank_1d(
values,
if v_ndim == 1 or arr.ndim == 1:
return algos.rank_1d(
arr,
is_datetimelike=is_datetimelike,
ties_method=method,
ascending=ascending,
na_option=na_option,
pct=pct,
)
elif values.ndim == 2:
ranks = algos.rank_2d(
values,
elif v_ndim == 2 or arr.ndim == 2:
return algos.rank_2d(
arr,
axis=axis,
is_datetimelike=is_datetimelike,
ties_method=method,
Expand All @@ -1079,8 +1086,6 @@ def rank(
else:
raise TypeError("Array with ndim > 2 are not supported.")

return ranks


# ---- #
# take #
Expand Down Expand Up @@ -1281,9 +1286,9 @@ def searchsorted(

if is_integer(value):
# We know that value is int
value = cast(int, dtype.type(value))
value = cast("int", dtype.type(value))
else:
value = pd_array(cast(ArrayLike, value), dtype=dtype)
value = pd_array(cast("ArrayLike", value), dtype=dtype)
else:
# E.g. if `arr` is an array with dtype='datetime64[ns]'
# and `value` is a pd.Timestamp, we may need to convert value
Expand Down
31 changes: 18 additions & 13 deletions pandas/core/arrays/categorical.py
Original file line number Diff line number Diff line change
Expand Up @@ -2105,24 +2105,29 @@ def _values_for_rank(self) -> np.ndarray:
numpy.array

"""
from pandas import Series
# Optimization: cache property lookups, minimize numpy conversion
ordered = self.ordered
codes = self.codes
categories = self.categories

if self.ordered:
values = self.codes
if ordered:
# codes is an ndarray, -1 means missing
values = codes
mask = values == -1
if mask.any():
# Only cast if missing values are present
values = values.astype("float64")
values[mask] = np.nan
elif is_any_real_numeric_dtype(self.categories.dtype):
values = np.array(self)
elif is_any_real_numeric_dtype(categories.dtype):
# codes is always numeric, so return directly instead of np.array(self)
values = codes
else:
# reorder the categories (so rank can use the float codes)
# instead of passing an object array to rank
values = np.array(
self.rename_categories(
Series(self.categories, copy=False).rank().values
)
)
# Take rank of categories, assign to codes
# Avoid recreating Series if categories is already an ndarray
from pandas import Series

ranked_categories = Series(categories, copy=False).rank().values
values = np.array(self.rename_categories(ranked_categories))
return values

def _hash_pandas_object(
Expand Down Expand Up @@ -2473,7 +2478,7 @@ def _mode(self, dropna: bool = True) -> Categorical:
mask = self.isna()

res_codes = algorithms.mode(codes, mask=mask)
res_codes = cast(np.ndarray, res_codes)
res_codes = cast("np.ndarray", res_codes)
assert res_codes.dtype == codes.dtype
res = self._from_backing_data(res_codes)
return res
Expand Down