Skip to content

Commit 186c081

Browse files
authored
ENH: More usage of maybe_unbox_numpy_scalars (#63431)
1 parent 70808b4 commit 186c081

File tree

6 files changed

+35
-18
lines changed

6 files changed

+35
-18
lines changed

pandas/core/frame.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,7 @@
9090
infer_dtype_from_scalar,
9191
invalidate_string_dtypes,
9292
maybe_downcast_to_dtype,
93+
maybe_unbox_numpy_scalar,
9394
)
9495
from pandas.core.dtypes.common import (
9596
infer_dtype_from_object,
@@ -12824,7 +12825,7 @@ def _get_data() -> DataFrame:
1282412825
df = df.astype(dtype)
1282512826
arr = concat_compat(list(df._iter_column_arrays()))
1282612827
return arr._reduce(name, skipna=skipna, keepdims=False, **kwds)
12827-
return func(df.values)
12828+
return maybe_unbox_numpy_scalar(func(df.values))
1282812829
elif axis == 1:
1282912830
if len(df.index) == 0:
1283012831
# Taking a transpose would result in no columns, losing the dtype.

pandas/core/indexes/base.py

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -963,10 +963,10 @@ def __array_ufunc__(self, ufunc: np.ufunc, method: str_t, *inputs, **kwargs):
963963
return tuple(self.__array_wrap__(x) for x in result)
964964
elif method == "reduce":
965965
result = lib.item_from_zerodim(result)
966-
return result
966+
return maybe_unbox_numpy_scalar(result)
967967
elif is_scalar(result):
968968
# e.g. matmul
969-
return result
969+
return maybe_unbox_numpy_scalar(result)
970970

971971
if result.dtype == np.float16:
972972
result = result.astype(np.float32)
@@ -6817,7 +6817,7 @@ def _searchsorted_monotonic(self, label, side: Literal["left", "right"] = "left"
68176817
pos = self[::-1].searchsorted(
68186818
label, side="right" if side == "left" else "left"
68196819
)
6820-
return len(self) - pos
6820+
return maybe_unbox_numpy_scalar(len(self) - pos)
68216821

68226822
raise ValueError("index must be monotonic increasing or decreasing")
68236823

@@ -7007,6 +7007,8 @@ def slice_locs(
70077007
if start_slice == -1:
70087008
start_slice -= len(self)
70097009

7010+
start_slice = maybe_unbox_numpy_scalar(start_slice)
7011+
end_slice = maybe_unbox_numpy_scalar(end_slice)
70107012
return start_slice, end_slice
70117013

70127014
def delete(
@@ -7414,7 +7416,7 @@ def any(self, *args, **kwargs):
74147416
# i.e. EA, call _reduce instead of "any" to get TypeError instead
74157417
# of AttributeError
74167418
return vals._reduce("any")
7417-
return np.any(vals)
7419+
return maybe_unbox_numpy_scalar(np.any(vals))
74187420

74197421
def all(self, *args, **kwargs):
74207422
"""
@@ -7462,7 +7464,7 @@ def all(self, *args, **kwargs):
74627464
# i.e. EA, call _reduce instead of "all" to get TypeError instead
74637465
# of AttributeError
74647466
return vals._reduce("all")
7465-
return np.all(vals)
7467+
return maybe_unbox_numpy_scalar(np.all(vals))
74667468

74677469
@final
74687470
def _maybe_disable_logical_methods(self, opname: str_t) -> None:

pandas/core/indexes/interval.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@
4040
infer_dtype_from_scalar,
4141
maybe_box_datetimelike,
4242
maybe_downcast_numeric,
43+
maybe_unbox_numpy_scalar,
4344
maybe_upcast_numeric_to_64bit,
4445
)
4546
from pandas.core.dtypes.common import (
@@ -812,7 +813,7 @@ def get_loc(self, key) -> int | slice | np.ndarray:
812813
if matches == 0:
813814
raise KeyError(key)
814815
if matches == 1:
815-
return mask.argmax()
816+
return maybe_unbox_numpy_scalar(mask.argmax())
816817

817818
res = lib.maybe_booleans_to_slice(mask.view("u1"))
818819
if isinstance(res, slice) and res.stop is None:

pandas/core/indexes/multi.py

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,10 @@
5858
)
5959
from pandas.util._exceptions import find_stack_level
6060

61-
from pandas.core.dtypes.cast import coerce_indexer_dtype
61+
from pandas.core.dtypes.cast import (
62+
coerce_indexer_dtype,
63+
maybe_unbox_numpy_scalar,
64+
)
6265
from pandas.core.dtypes.common import (
6366
ensure_int64,
6467
ensure_platform_int,
@@ -3132,7 +3135,9 @@ def get_slice_bound(
31323135
"""
31333136
if not isinstance(label, tuple):
31343137
label = (label,)
3135-
return self._partial_tup_index(label, side=side)
3138+
result = self._partial_tup_index(label, side=side)
3139+
result = maybe_unbox_numpy_scalar(result)
3140+
return result
31363141

31373142
def slice_locs(self, start=None, end=None, step=None) -> tuple[int, int]:
31383143
"""
@@ -3719,7 +3724,7 @@ def convert_indexer(start, stop, step, indexer=indexer, codes=level_codes):
37193724
if start == end:
37203725
# The label is present in self.levels[level] but unused:
37213726
raise KeyError(key)
3722-
return slice(start, end)
3727+
return slice(maybe_unbox_numpy_scalar(start), maybe_unbox_numpy_scalar(end))
37233728

37243729
def get_locs(self, seq) -> npt.NDArray[np.intp]:
37253730
"""

pandas/core/series.py

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2667,7 +2667,7 @@ def quantile(
26672667
return self._constructor(result, index=idx, name=self.name)
26682668
else:
26692669
# scalar
2670-
return result.iloc[0]
2670+
return maybe_unbox_numpy_scalar(result.iloc[0])
26712671

26722672
def corr(
26732673
self,
@@ -2754,9 +2754,11 @@ def corr(
27542754
other_values = other.to_numpy(dtype=float, na_value=np.nan, copy=False)
27552755

27562756
if method in ["pearson", "spearman", "kendall"] or callable(method):
2757-
return nanops.nancorr(
2757+
result = nanops.nancorr(
27582758
this_values, other_values, method=method, min_periods=min_periods
27592759
)
2760+
result = maybe_unbox_numpy_scalar(result)
2761+
return result
27602762

27612763
raise ValueError(
27622764
"method must be either 'pearson', "
@@ -2808,9 +2810,11 @@ def cov(
28082810
return np.nan
28092811
this_values = this.to_numpy(dtype=float, na_value=np.nan, copy=False)
28102812
other_values = other.to_numpy(dtype=float, na_value=np.nan, copy=False)
2811-
return nanops.nancov(
2813+
result = nanops.nancov(
28122814
this_values, other_values, min_periods=min_periods, ddof=ddof
28132815
)
2816+
result = maybe_unbox_numpy_scalar(result)
2817+
return result
28142818

28152819
@doc(
28162820
klass="Series",
@@ -3023,11 +3027,12 @@ def dot(self, other: AnyArrayLike | DataFrame) -> Series | np.ndarray:
30233027
np.dot(lvals, rvals), index=other.columns, copy=False, dtype=common_type
30243028
).__finalize__(self, method="dot")
30253029
elif isinstance(other, Series):
3026-
return np.dot(lvals, rvals)
3030+
result = np.dot(lvals, rvals)
30273031
elif isinstance(rvals, np.ndarray):
3028-
return np.dot(lvals, rvals)
3032+
result = np.dot(lvals, rvals)
30293033
else: # pragma: no cover
30303034
raise TypeError(f"unsupported type: {type(other)}")
3035+
return maybe_unbox_numpy_scalar(result)
30313036

30323037
def __matmul__(self, other):
30333038
"""
@@ -5701,7 +5706,7 @@ def pop(self, item: Hashable) -> Any:
57015706
2 3
57025707
dtype: int64
57035708
"""
5704-
return super().pop(item=item)
5709+
return maybe_unbox_numpy_scalar(super().pop(item=item))
57055710

57065711
def info(
57075712
self,

pandas/tests/series/test_ufunc.py

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -433,10 +433,13 @@ def test_np_matmul():
433433

434434

435435
@pytest.mark.parametrize("box", [pd.Index, pd.Series])
436-
def test_np_matmul_1D(box):
436+
def test_np_matmul_1D(box, using_python_scalars):
437437
result = np.matmul(box([1, 2]), box([2, 3]))
438438
assert result == 8
439-
assert isinstance(result, np.int64)
439+
if using_python_scalars:
440+
assert type(result) == int, type(result)
441+
else:
442+
assert type(result) == np.int64, type(result)
440443

441444

442445
def test_array_ufuncs_for_many_arguments():

0 commit comments

Comments
 (0)