Skip to content

Commit 1633e32

Browse files
authored
PERF: nanops (#43311)
1 parent a826be1 commit 1633e32

File tree

1 file changed

+33
-0
lines changed

1 file changed

+33
-0
lines changed

pandas/core/nanops.py

+33
Original file line numberDiff line numberDiff line change
@@ -449,6 +449,35 @@ def _na_for_min_count(values: np.ndarray, axis: int | None) -> Scalar | np.ndarr
449449
return np.full(result_shape, fill_value, dtype=values.dtype)
450450

451451

452+
def maybe_operate_rowwise(func):
453+
"""
454+
NumPy operations on C-contiguous ndarrays with axis=1 can be
455+
very slow. Operate row-by-row and concatenate the results.
456+
"""
457+
458+
@functools.wraps(func)
459+
def newfunc(values: np.ndarray, *, axis: int | None = None, **kwargs):
460+
if (
461+
axis == 1
462+
and values.ndim == 2
463+
and values.flags["C_CONTIGUOUS"]
464+
and values.dtype != object
465+
):
466+
arrs = list(values)
467+
if kwargs.get("mask") is not None:
468+
mask = kwargs.pop("mask")
469+
results = [
470+
func(arrs[i], mask=mask[i], **kwargs) for i in range(len(arrs))
471+
]
472+
else:
473+
results = [func(x, **kwargs) for x in arrs]
474+
return np.array(results)
475+
476+
return func(values, axis=axis, **kwargs)
477+
478+
return newfunc
479+
480+
452481
def nanany(
453482
values: np.ndarray,
454483
*,
@@ -543,6 +572,7 @@ def nanall(
543572

544573
@disallow("M8")
545574
@_datetimelike_compat
575+
@maybe_operate_rowwise
546576
def nansum(
547577
values: np.ndarray,
548578
*,
@@ -1111,6 +1141,7 @@ def nanargmin(
11111141

11121142

11131143
@disallow("M8", "m8")
1144+
@maybe_operate_rowwise
11141145
def nanskew(
11151146
values: np.ndarray,
11161147
*,
@@ -1198,6 +1229,7 @@ def nanskew(
11981229

11991230

12001231
@disallow("M8", "m8")
1232+
@maybe_operate_rowwise
12011233
def nankurt(
12021234
values: np.ndarray,
12031235
*,
@@ -1294,6 +1326,7 @@ def nankurt(
12941326

12951327

12961328
@disallow("M8", "m8")
1329+
@maybe_operate_rowwise
12971330
def nanprod(
12981331
values: np.ndarray,
12991332
*,

0 commit comments

Comments
 (0)