Skip to content

Commit 623be5d

Browse files
authored
Merge pull request #1647 from scipy/1.18/stats/new-params
👽️ `stats`: new `axis`, `keepdims`, and `nan_policy` keyword parameters
2 parents 18d0015 + df81352 commit 623be5d

7 files changed

Lines changed: 106 additions & 72 deletions

File tree

.mypyignore

Lines changed: 1 addition & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -17,31 +17,5 @@ scipy\.special\._precompute\..*
1717
# useless __new__
1818
scipy\.stats\.(_new_distributions\.)?Normal\.__new__
1919

20-
###
21-
# TODO: 1.18.0rc1
22-
23-
scipy.stats._bws_test.bws_test
24-
25-
scipy.stats._morestats.ansari
26-
scipy.stats._morestats.boxcox
27-
scipy.stats._morestats.boxcox_normmax
28-
scipy.stats._morestats.yeojohnson
29-
scipy.stats._morestats.yeojohnson_normmax
30-
scipy.stats.morestats.ansari
31-
scipy.stats.morestats.boxcox
32-
scipy.stats.morestats.boxcox_normmax
33-
scipy.stats.morestats.yeojohnson
34-
scipy.stats.morestats.yeojohnson_normmax
35-
36-
scipy.stats._stats_py.__all__
37-
scipy.stats._stats_py.expectile
38-
scipy.stats._stats_py.obrientransform
39-
scipy.stats._stats_py.quantile_test
40-
scipy.stats._stats_py.quantile_test_iv
41-
scipy.stats._stats_py.sigmaclip
42-
scipy.stats.stats.obrientransform
43-
scipy.stats.stats.sigmaclip
44-
4520
# https://github.com/scipy/scipy/pull/25240
46-
scipy.stats._multicomp.DunnettResult.__init__
47-
scipy.stats._multicomp.DunnettResult.__match_args__
21+
scipy\.stats\._multicomp\.DunnettResult\.(__init__|__match_args__)

scipy-stubs/stats/__init__.pyi

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ from ._binned_statistic import binned_statistic, binned_statistic_2d, binned_sta
33
from ._binomtest import binomtest
44
from ._bws_test import bws_test
55
from ._censored_data import CensoredData
6-
from ._correlation import chatterjeexi, spearmanrho
6+
from ._correlation import chatterjeexi, siegelslopes, spearmanrho, theilslopes
77
from ._covariance import Covariance
88
from ._distribution_infrastructure import Mixture, abs, exp, log, make_distribution, order_statistic, truncate
99
from ._entropy import differential_entropy, entropy
@@ -130,12 +130,10 @@ from ._stats_py import (
130130
relfreq,
131131
scoreatpercentile,
132132
sem,
133-
siegelslopes,
134133
sigmaclip,
135134
skew,
136135
skewtest,
137136
spearmanr,
138-
theilslopes,
139137
tiecorrect,
140138
tmax,
141139
tmean,

scipy-stubs/stats/_bws_test.pyi

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,5 +9,6 @@ def bws_test(
99
y: onp.ToComplex1D,
1010
*,
1111
alternative: Literal["two-sided", "less", "greater"] = "two-sided",
12+
axis: int | None = 0,
1213
method: PermutationMethod | None = None,
1314
) -> PermutationTestResult: ...

scipy-stubs/stats/_morestats.pyi

Lines changed: 50 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@ from typing import (
99
Protocol,
1010
Self,
1111
SupportsIndex,
12-
TypeAlias,
1312
final,
1413
overload,
1514
override,
@@ -65,7 +64,6 @@ __all__ = [
6564

6665
###
6766

68-
_T = TypeVar("_T")
6967
_FloatingT = TypeVar("_FloatingT", bound=npc.floating)
7068
_NDT_co = TypeVar(
7169
"_NDT_co",
@@ -74,15 +72,15 @@ _NDT_co = TypeVar(
7472
default=np.float64 | onp.ArrayND[np.float64],
7573
) # fmt: skip
7674

77-
_JustAnyShape: TypeAlias = tuple[Never, Never, Never, Never] # workaround for https://github.com/microsoft/pyright/issues/10232
78-
_Tuple2: TypeAlias = tuple[_T, _T]
79-
_Tuple3: TypeAlias = tuple[_T, _T, _T]
80-
_Float1D: TypeAlias = onp.Array1D[np.float64]
75+
type _JustAnyShape = tuple[Never, Never, Never, Never] # workaround for https://github.com/microsoft/pyright/issues/10232
76+
type _Tuple2[T] = tuple[T, T]
77+
type _Tuple3[T] = tuple[T, T, T]
78+
type _Float1D = onp.Array1D[np.float64]
8179

82-
_KStatOrder: TypeAlias = Literal[1, 2, 3, 4]
83-
_CenterMethod: TypeAlias = Literal["mean", "median", "trimmed"]
84-
_RVCAnderson: TypeAlias = Literal["norm", "expon", "logistic", "extreme1", "gumbel", "gumbel_l", "gumbel_r", "weibull_min"]
85-
_RVC0: TypeAlias = Literal[
80+
type _KStatOrder = Literal[1, 2, 3, 4]
81+
type _CenterMethod = Literal["mean", "median", "trimmed"]
82+
type _RVCAnderson = Literal["norm", "expon", "logistic", "extreme1", "gumbel", "gumbel_l", "gumbel_r", "weibull_min"]
83+
type _RVC0 = Literal[
8684
"anglit",
8785
"arcsine",
8886
"cauchy",
@@ -108,7 +106,7 @@ _RVC0: TypeAlias = Literal[
108106
"uniform",
109107
"wald",
110108
]
111-
_RVC1: TypeAlias = Literal[
109+
type _RVC1 = Literal[
112110
"alpha",
113111
"argus",
114112
"bradford",
@@ -152,11 +150,12 @@ _RVC1: TypeAlias = Literal[
152150
"weibull_min",
153151
"wrapcauchy",
154152
]
153+
type _AnsariMethod = Literal["auto", "asymptotic", "exact"]
155154

156-
_ObjFun1D: TypeAlias = Callable[[float], float | npc.floating]
157-
_MinFun1D: TypeAlias = Callable[[_ObjFun1D], _HasX] | Callable[[_ObjFun1D], OptimizeResult]
155+
type _ObjFun1D = Callable[[float], float | npc.floating]
156+
type _MinFun1D = Callable[[_ObjFun1D], _HasX] | Callable[[_ObjFun1D], OptimizeResult]
158157

159-
_AndersonResult: TypeAlias = FitResult[Callable[[onp.ToFloat, onp.ToFloat], np.float64]]
158+
type _AndersonResult = FitResult[Callable[[onp.ToFloat, onp.ToFloat], np.float64]]
160159

161160
@type_check_only
162161
class _TestResult(NamedTuple, Generic[_NDT_co]):
@@ -661,24 +660,36 @@ def yeojohnson_llf(
661660
#
662661
@overload
663662
def boxcox(
664-
x: onp.ToFloat1D, lmbda: None = None, alpha: None = None, optimizer: _MinFun1D | None = None
663+
x: onp.ToFloat1D,
664+
lmbda: None = None,
665+
alpha: None = None,
666+
optimizer: _MinFun1D | None = None,
667+
*,
668+
nan_policy: NanPolicy = "propagate",
665669
) -> tuple[_Float1D, np.float64]: ...
666670
@overload
667-
def boxcox(x: onp.ToFloat1D, lmbda: onp.ToFloat, alpha: float | None = None, optimizer: _MinFun1D | None = None) -> _Float1D: ...
671+
def boxcox(
672+
x: onp.ToFloat1D,
673+
lmbda: onp.ToFloat,
674+
alpha: float | None = None,
675+
optimizer: _MinFun1D | None = None,
676+
*,
677+
nan_policy: NanPolicy = "propagate",
678+
) -> _Float1D: ...
668679
@overload
669680
def boxcox(
670-
x: onp.ToFloat1D, lmbda: None, alpha: float, optimizer: _MinFun1D | None = None
681+
x: onp.ToFloat1D, lmbda: None, alpha: float, optimizer: _MinFun1D | None = None, *, nan_policy: NanPolicy = "propagate"
671682
) -> tuple[_Float1D, np.float64, _Tuple2[float]]: ...
672683
@overload
673684
def boxcox(
674-
x: onp.ToFloat1D, lmbda: None = None, *, alpha: float, optimizer: _MinFun1D | None = None
685+
x: onp.ToFloat1D, lmbda: None = None, *, alpha: float, optimizer: _MinFun1D | None = None, nan_policy: NanPolicy = "propagate"
675686
) -> tuple[_Float1D, np.float64, _Tuple2[float]]: ...
676687

677688
#
678689
@overload
679-
def yeojohnson(x: onp.ToFloat1D, lmbda: None = None) -> tuple[_Float1D, np.float64]: ...
690+
def yeojohnson(x: onp.ToFloat1D, lmbda: None = None, *, nan_policy: NanPolicy = "propagate") -> tuple[_Float1D, np.float64]: ...
680691
@overload
681-
def yeojohnson(x: onp.ToFloat1D, lmbda: onp.ToFloat) -> _Float1D: ...
692+
def yeojohnson(x: onp.ToFloat1D, lmbda: onp.ToFloat, *, nan_policy: NanPolicy = "propagate") -> _Float1D: ...
682693

683694
#
684695
@overload
@@ -689,6 +700,7 @@ def boxcox_normmax(
689700
optimizer: _MinFun1D | None = None,
690701
*,
691702
ymax: onp.ToFloat | _BigFloat = ...,
703+
nan_policy: NanPolicy = "propagate",
692704
) -> np.float64: ...
693705
@overload
694706
def boxcox_normmax(
@@ -698,6 +710,7 @@ def boxcox_normmax(
698710
optimizer: _MinFun1D | None = None,
699711
*,
700712
ymax: onp.ToFloat | _BigFloat = ...,
713+
nan_policy: NanPolicy = "propagate",
701714
) -> onp.Array1D[np.float64]: ...
702715
@overload
703716
def boxcox_normmax(
@@ -707,19 +720,29 @@ def boxcox_normmax(
707720
method: Literal["all"],
708721
optimizer: _MinFun1D | None = None,
709722
ymax: onp.ToFloat | _BigFloat = ...,
723+
nan_policy: NanPolicy = "propagate",
710724
) -> onp.Array1D[np.float64]: ...
711725

712726
#
713727
@overload
714728
def yeojohnson_normmax(
715-
x: onp.ArrayND[npc.floating | npc.integer, _JustAnyShape], brack: _Tuple2[onp.ToFloat] | None = None
729+
x: onp.ArrayND[npc.floating | npc.integer, _JustAnyShape],
730+
brack: _Tuple2[onp.ToFloat] | None = None,
731+
*,
732+
nan_policy: NanPolicy = "propagate",
716733
) -> onp.Array1D[np.float64] | np.float64: ...
717734
@overload
718-
def yeojohnson_normmax(x: onp.ToFloatStrict1D, brack: _Tuple2[onp.ToFloat] | None = None) -> np.float64: ...
735+
def yeojohnson_normmax(
736+
x: onp.ToFloatStrict1D, brack: _Tuple2[onp.ToFloat] | None = None, *, nan_policy: NanPolicy = "propagate"
737+
) -> np.float64: ...
719738
@overload
720-
def yeojohnson_normmax(x: onp.ToFloatStrict2D, brack: _Tuple2[onp.ToFloat] | None = None) -> onp.Array1D[np.float64]: ...
739+
def yeojohnson_normmax(
740+
x: onp.ToFloatStrict2D, brack: _Tuple2[onp.ToFloat] | None = None, *, nan_policy: NanPolicy = "propagate"
741+
) -> onp.Array1D[np.float64]: ...
721742
@overload
722-
def yeojohnson_normmax(x: onp.ToFloatND, brack: _Tuple2[onp.ToFloat] | None = None) -> onp.Array1D[np.float64] | np.float64: ...
743+
def yeojohnson_normmax(
744+
x: onp.ToFloatND, brack: _Tuple2[onp.ToFloat] | None = None, *, nan_policy: NanPolicy = "propagate"
745+
) -> onp.Array1D[np.float64] | np.float64: ...
723746

724747
#
725748
def boxcox_normplot(
@@ -798,6 +821,7 @@ def ansari(
798821
alternative: Alternative = "two-sided",
799822
*,
800823
axis: None,
824+
method: _AnsariMethod = "auto",
801825
nan_policy: NanPolicy = "propagate",
802826
keepdims: Literal[False] = False,
803827
) -> AnsariResult[np.float64]: ...
@@ -808,6 +832,7 @@ def ansari(
808832
alternative: Alternative = "two-sided",
809833
*,
810834
axis: SupportsIndex | None = 0,
835+
method: _AnsariMethod = "auto",
811836
nan_policy: NanPolicy = "propagate",
812837
keepdims: Literal[True],
813838
) -> AnsariResult[onp.ArrayND[np.float64]]: ...
@@ -818,6 +843,7 @@ def ansari(
818843
alternative: Alternative = "two-sided",
819844
*,
820845
axis: SupportsIndex | None = 0,
846+
method: _AnsariMethod = "auto",
821847
nan_policy: NanPolicy = "propagate",
822848
keepdims: bool = False,
823849
) -> AnsariResult: ...

scipy-stubs/stats/_stats_py.pyi

Lines changed: 38 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@ import optype as op
1010
import optype.numpy as onp
1111
import optype.numpy.compat as npc
1212

13-
from ._correlation import siegelslopes, theilslopes
1413
from ._resampling import BootstrapMethod, ResamplingMethod
1514
from ._typing import Alternative, BaseBunch, BunchMixin, NanPolicy, PowerDivergenceStatistic
1615

@@ -57,12 +56,10 @@ __all__ = [
5756
"relfreq",
5857
"scoreatpercentile",
5958
"sem",
60-
"siegelslopes",
6159
"sigmaclip",
6260
"skew",
6361
"skewtest",
6462
"spearmanr",
65-
"theilslopes",
6663
"tiecorrect",
6764
"tmax",
6865
"tmean",
@@ -2984,7 +2981,9 @@ def relfreq(
29842981
) -> RelfreqResult: ...
29852982

29862983
#
2987-
def obrientransform(*samples: onp.ToFloatND) -> onp.Array2D[np.float64] | onp.Array1D[np.object_]: ...
2984+
def obrientransform(
2985+
*samples: onp.ToFloatND, nan_policy: NanPolicy = "propagate"
2986+
) -> onp.Array2D[np.float64] | onp.Array1D[np.object_]: ...
29882987

29892988
#
29902989
@overload # 1d ~inexact64 | +integer, keepdims=False (default)
@@ -3355,17 +3354,25 @@ def median_abs_deviation(
33553354

33563355
#
33573356
@overload
3358-
def sigmaclip(a: onp.ArrayND[_IntegerT], low: float = 4.0, high: float = 4.0) -> SigmaclipResult[_IntegerT, np.float64]: ...
3357+
def sigmaclip(
3358+
a: onp.ArrayND[_IntegerT], low: float = 4.0, high: float = 4.0, *, nan_policy: NanPolicy = "propagate"
3359+
) -> SigmaclipResult[_IntegerT, np.float64]: ...
33593360
@overload
3360-
def sigmaclip(a: onp.ArrayND[_FloatT], low: float = 4.0, high: float = 4.0) -> SigmaclipResult[_FloatT, _FloatT]: ...
3361+
def sigmaclip(
3362+
a: onp.ArrayND[_FloatT], low: float = 4.0, high: float = 4.0, *, nan_policy: NanPolicy = "propagate"
3363+
) -> SigmaclipResult[_FloatT, _FloatT]: ...
33613364
@overload
3362-
def sigmaclip(a: onp.SequenceND[int], low: float = 4.0, high: float = 4.0) -> SigmaclipResult[np.int_, np.float64]: ...
3365+
def sigmaclip(
3366+
a: onp.SequenceND[int], low: float = 4.0, high: float = 4.0, *, nan_policy: NanPolicy = "propagate"
3367+
) -> SigmaclipResult[np.int_, np.float64]: ...
33633368
@overload
33643369
def sigmaclip(
3365-
a: onp.SequenceND[list[float]] | list[float], low: float = 4.0, high: float = 4.0
3370+
a: onp.SequenceND[list[float]] | list[float], low: float = 4.0, high: float = 4.0, *, nan_policy: NanPolicy = "propagate"
33663371
) -> SigmaclipResult[np.float64, np.float64]: ...
33673372
@overload
3368-
def sigmaclip(a: onp.ToFloatND, low: float = 4.0, high: float = 4.0) -> SigmaclipResult: ...
3373+
def sigmaclip(
3374+
a: onp.ToFloatND, low: float = 4.0, high: float = 4.0, *, nan_policy: NanPolicy = "propagate"
3375+
) -> SigmaclipResult: ...
33693376

33703377
# TODO(jorenham): improve
33713378
def trimboth(a: onp.ToFloatND, proportiontocut: float, axis: int | None = 0) -> onp.ArrayND[_Real0D]: ...
@@ -5010,12 +5017,23 @@ def fisher_exact(
50105017

50115018
# undocumented
50125019
def quantile_test_iv(
5013-
x: onp.ToFloatND, q: float | _Real0D, p: float | npc.floating, alternative: Alternative
5020+
x: onp.ToFloatND,
5021+
q: float | _Real0D,
5022+
p: float | npc.floating,
5023+
alternative: Alternative,
5024+
axis: int | None,
5025+
keepdims: bool | None,
50145026
) -> tuple[onp.ArrayND[_Real0D], _Real0D, npc.floating, Alternative]: ...
50155027

50165028
#
50175029
def quantile_test(
5018-
x: onp.ToFloatND, *, q: float | _Real0D = 0, p: float | npc.floating = 0.5, alternative: Alternative = "two-sided"
5030+
x: onp.ToFloatND,
5031+
*,
5032+
q: float | _Real0D = 0.0,
5033+
p: float | npc.floating = 0.5,
5034+
alternative: Alternative = "two-sided",
5035+
axis: int | None = 0,
5036+
keepdims: bool | None = None,
50195037
) -> QuantileTestResult: ...
50205038

50215039
#
@@ -5069,7 +5087,15 @@ def rankdata(
50695087
) -> onp.ArrayND[np.float64]: ...
50705088

50715089
#
5072-
def expectile(a: onp.ToFloatND, alpha: float = 0.5, *, weights: onp.ToFloatND | None = None) -> np.float64: ...
5090+
def expectile(
5091+
a: onp.ToFloatND,
5092+
alpha: float = 0.5,
5093+
*,
5094+
weights: onp.ToFloatND | None = None,
5095+
axis: int | None = None,
5096+
nan_policy: NanPolicy = "propagate",
5097+
keepdims: bool = False,
5098+
) -> np.float64: ...
50735099

50745100
#
50755101
@overload # ?d, ?d

scipy-stubs/stats/morestats.pyi

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -66,21 +66,29 @@ def boxcox_llf(
6666
lmb: object, data: object, *, axis: object = 0, keepdims: object = False, nan_policy: object = "propagate"
6767
) -> object: ...
6868
@deprecated("will be removed in SciPy v2.0.0")
69-
def boxcox(x: object, lmbda: object = None, alpha: object = None, optimizer: object = None) -> object: ...
69+
def boxcox(
70+
x: object, lmbda: object = None, alpha: object = None, optimizer: object = None, *, nan_policy: str = "propagate"
71+
) -> object: ...
7072
@deprecated("will be removed in SciPy v2.0.0")
7173
def boxcox_normmax(
72-
x: object, brack: object = None, method: object = "pearsonr", optimizer: object = None, *, ymax: object = ...
74+
x: object,
75+
brack: object = None,
76+
method: object = "pearsonr",
77+
optimizer: object = None,
78+
*,
79+
ymax: object = ...,
80+
nan_policy: str = "propagate",
7381
) -> object: ...
7482
@deprecated("will be removed in SciPy v2.0.0")
7583
def boxcox_normplot(x: object, la: object, lb: object, plot: object = None, N: object = 80) -> object: ...
7684
@deprecated("will be removed in SciPy v2.0.0")
77-
def yeojohnson(x: object, lmbda: object = None) -> object: ...
85+
def yeojohnson(x: object, lmbda: object = None, *, nan_policy: str = "propagate") -> object: ...
7886
@deprecated("will be removed in SciPy v2.0.0")
7987
def yeojohnson_llf(
8088
lmb: object, data: object, *, axis: object = 0, nan_policy: object = "propagate", keepdims: object = False
8189
) -> object: ...
8290
@deprecated("will be removed in SciPy v2.0.0")
83-
def yeojohnson_normmax(x: object, brack: object = None) -> object: ...
91+
def yeojohnson_normmax(x: object, brack: object = None, *, nan_policy: str = "propagate") -> object: ...
8492
@deprecated("will be removed in SciPy v2.0.0")
8593
def yeojohnson_normplot(x: object, la: object, lb: object, plot: object = None, N: object = 80) -> object: ...
8694
@deprecated("will be removed in SciPy v2.0.0")
@@ -96,6 +104,7 @@ def ansari(
96104
alternative: object = "two-sided",
97105
*,
98106
axis: object = 0,
107+
method: str = "auto",
99108
nan_policy: object = "propagate",
100109
keepdims: object = False,
101110
) -> object: ...

0 commit comments

Comments
 (0)