From 936c94b66787514d9b43fcf5d026a8634423859c Mon Sep 17 00:00:00 2001 From: MomIsBestFriend <> Date: Wed, 25 Dec 2019 03:56:54 +0200 Subject: [PATCH 01/11] TYP: Annotations in pandas/core/nanops.py --- pandas/core/nanops.py | 135 ++++++++++++++++++++++++++++++++---------- 1 file changed, 105 insertions(+), 30 deletions(-) diff --git a/pandas/core/nanops.py b/pandas/core/nanops.py index 1079f516a4e40..2692948e8d329 100644 --- a/pandas/core/nanops.py +++ b/pandas/core/nanops.py @@ -1,13 +1,14 @@ import functools import itertools import operator -from typing import Any, Optional, Tuple, Union +from typing import Any, Callable, Optional, Tuple, Union import numpy as np from pandas._config import get_option from pandas._libs import NaT, Timedelta, Timestamp, iNaT, lib +from pandas._typing import Dtype, Scalar from pandas.compat._optional import import_optional_dependency from pandas.core.dtypes.cast import _int64_max, maybe_upcast_putmask @@ -37,7 +38,7 @@ _USE_BOTTLENECK = False -def set_use_bottleneck(v=True): +def set_use_bottleneck(v: bool = True) -> None: # set/unset to use bottleneck global _USE_BOTTLENECK if _BOTTLENECK_INSTALLED: @@ -55,7 +56,7 @@ def __init__(self, *dtypes): def check(self, obj) -> bool: return hasattr(obj, "dtype") and issubclass(obj.dtype.type, self.dtypes) - def __call__(self, f): + def __call__(self, f) -> Callable: @functools.wraps(f) def _f(*args, **kwargs): obj_iter = itertools.chain(args, kwargs.values()) @@ -80,11 +81,11 @@ def _f(*args, **kwargs): class bottleneck_switch: - def __init__(self, name=None, **kwargs): + def __init__(self, name: Optional[str] = None, **kwargs): self.name = name self.kwargs = kwargs - def __call__(self, alt): + def __call__(self, alt: Callable) -> Callable: bn_name = self.name or alt.__name__ try: @@ -93,7 +94,9 @@ def __call__(self, alt): bn_func = None @functools.wraps(alt) - def f(values, axis=None, skipna=True, **kwds): + def f( + values: np.ndarray, axis: Optional[int] = None, skipna: bool = True, **kwds + ): if len(self.kwargs) > 0: for k, v in self.kwargs.items(): if k not in kwds: @@ -129,7 +132,7 @@ def f(values, axis=None, skipna=True, **kwds): return f -def _bn_ok_dtype(dt, name: str) -> bool: +def _bn_ok_dtype(dt: Dtype, name: str) -> bool: # Bottleneck chokes on datetime64 if not is_object_dtype(dt) and not ( is_datetime_or_timedelta_dtype(dt) or is_datetime64tz_dtype(dt) @@ -163,7 +166,9 @@ def _has_infs(result) -> bool: return False -def _get_fill_value(dtype, fill_value=None, fill_value_typ=None): +def _get_fill_value( + dtype: Dtype, fill_value: Any = None, fill_value_typ: Optional[str] = None +): """ return the correct fill value for the dtype of the values """ if fill_value is not None: return fill_value @@ -326,12 +331,12 @@ def _get_values( return values, mask, dtype, dtype_max, fill_value -def _na_ok_dtype(dtype): +def _na_ok_dtype(dtype) -> bool: # TODO: what about datetime64tz? PeriodDtype? return not issubclass(dtype.type, (np.integer, np.timedelta64, np.datetime64)) -def _wrap_results(result, dtype, fill_value=None): +def _wrap_results(result, dtype: Dtype, fill_value=None): """ wrap our results if needed """ if is_datetime64_dtype(dtype) or is_datetime64tz_dtype(dtype): @@ -362,7 +367,9 @@ def _wrap_results(result, dtype, fill_value=None): return result -def _na_for_min_count(values, axis: Optional[int]): +def _na_for_min_count( + values: np.ndarray, axis: Optional[int] +) -> Union[Scalar, np.ndarray]: """ Return the missing value for `values`. @@ -393,7 +400,12 @@ def _na_for_min_count(values, axis: Optional[int]): return result -def nanany(values, axis=None, skipna: bool = True, mask=None): +def nanany( + values: np.ndarray, + axis: Optional[int] = None, + skipna: bool = True, + mask: Optional[np.ndarray] = None, +) -> bool: """ Check if any elements along an axis evaluate to True. @@ -425,7 +437,12 @@ def nanany(values, axis=None, skipna: bool = True, mask=None): return values.any(axis) -def nanall(values, axis=None, skipna: bool = True, mask=None): +def nanall( + values: np.ndarray, + axis: Optional[int] = None, + skipna: bool = True, + mask: Optional[np.ndarray] = None, +) -> bool: """ Check if all elements along an axis evaluate to True. @@ -458,7 +475,13 @@ def nanall(values, axis=None, skipna: bool = True, mask=None): @disallow("M8") -def nansum(values, axis=None, skipna=True, min_count=0, mask=None): +def nansum( + values: np.ndarray, + axis: Optional[int] = None, + skipna: bool = True, + min_count: int = 0, + mask: Optional[np.ndarray] = None, +) -> Dtype: """ Sum the elements along an axis ignoring NaNs @@ -629,7 +652,7 @@ def _get_counts_nanvar( mask: Optional[np.ndarray], axis: Optional[int], ddof: int, - dtype=float, + dtype: Dtype = float, ) -> Tuple[Union[int, np.ndarray], Union[int, np.ndarray]]: """ Get the count of non-null values along an axis, accounting for degrees of freedom. @@ -776,7 +799,13 @@ def nanvar(values, axis=None, skipna=True, ddof=1, mask=None): @disallow("M8", "m8") -def nansem(values, axis=None, skipna=True, ddof=1, mask=None): +def nansem( + values: np.ndarray, + axis: Optional[int] = None, + skipna: bool = True, + ddof: int = 1, + mask: Optional[np.ndarray] = None, +) -> float: """ Compute the standard error in the mean along given axis while ignoring NaNs @@ -819,9 +848,14 @@ def nansem(values, axis=None, skipna=True, ddof=1, mask=None): return np.sqrt(var) / np.sqrt(count) -def _nanminmax(meth, fill_value_typ): +def _nanminmax(meth: str, fill_value_typ: str) -> Callable: @bottleneck_switch(name="nan" + meth) - def reduction(values, axis=None, skipna=True, mask=None): + def reduction( + values: np.ndarray, + axis: Optional[int] = None, + skipna: bool = True, + mask: Optional[np.ndarray] = None, + ) -> np.ndarray: values, mask, dtype, dtype_max, fill_value = _get_values( values, skipna, fill_value_typ=fill_value_typ, mask=mask @@ -847,7 +881,12 @@ def reduction(values, axis=None, skipna=True, mask=None): @disallow("O") -def nanargmax(values, axis=None, skipna=True, mask=None): +def nanargmax( + values: np.ndarray, + axis: Optional[int] = None, + skipna: bool = True, + mask: Optional[np.ndarray] = None, +) -> int: """ Parameters ---------- @@ -878,7 +917,12 @@ def nanargmax(values, axis=None, skipna=True, mask=None): @disallow("O") -def nanargmin(values, axis=None, skipna=True, mask=None): +def nanargmin( + values: np.ndarray, + axis: Optional[int] = None, + skipna: bool = True, + mask: Optional[np.ndarray] = None, +) -> int: """ Parameters ---------- @@ -909,7 +953,12 @@ def nanargmin(values, axis=None, skipna=True, mask=None): @disallow("M8", "m8") -def nanskew(values, axis=None, skipna=True, mask=None): +def nanskew( + values: np.ndarray, + axis: Optional[int] = None, + skipna: bool = True, + mask: Optional[np.ndarray] = None, +) -> float: """ Compute the sample skewness. The statistic computed here is the adjusted Fisher-Pearson standardized @@ -987,7 +1036,12 @@ def nanskew(values, axis=None, skipna=True, mask=None): @disallow("M8", "m8") -def nankurt(values, axis=None, skipna=True, mask=None): +def nankurt( + values: np.ndarray, + axis: Optional[int] = None, + skipna: bool = True, + mask: Optional[np.ndarray] = None, +) -> float: """ Compute the sample excess kurtosis @@ -1075,7 +1129,13 @@ def nankurt(values, axis=None, skipna=True, mask=None): @disallow("M8", "m8") -def nanprod(values, axis=None, skipna=True, min_count=0, mask=None): +def nanprod( + values: np.ndarray, + axis: Optional[int] = None, + skipna: bool = True, + min_count: int = 0, + mask: Optional[np.ndarray] = None, +) -> Dtype: """ Parameters ---------- @@ -1138,7 +1198,7 @@ def _get_counts( values_shape: Tuple[int], mask: Optional[np.ndarray], axis: Optional[int], - dtype=float, + dtype: Dtype = float, ) -> Union[int, np.ndarray]: """ Get the count of non-null values along an axis @@ -1218,7 +1278,12 @@ def _zero_out_fperr(arg): @disallow("M8", "m8") -def nancorr(a, b, method="pearson", min_periods=None): +def nancorr( + a: np.ndarray, + b: np.ndarray, + method: str = "pearson", + min_periods: Optional[int] = None, +): """ a, b: ndarrays """ @@ -1240,7 +1305,7 @@ def nancorr(a, b, method="pearson", min_periods=None): return f(a, b) -def get_corr_func(method): +def get_corr_func(method: str): if method in ["kendall", "spearman"]: from scipy.stats import kendalltau, spearmanr elif callable(method): @@ -1262,7 +1327,7 @@ def _spearman(a, b): @disallow("M8", "m8") -def nancov(a, b, min_periods=None): +def nancov(a: np.ndarray, b: np.ndarray, min_periods: Optional[int] = None): if len(a) != len(b): raise AssertionError("Operands to nancov must have same size") @@ -1308,7 +1373,7 @@ def _ensure_numeric(x): # NA-friendly array comparisons -def make_nancomp(op): +def make_nancomp(op) -> Callable: def f(x, y): xmask = isna(x) ymask = isna(y) @@ -1335,7 +1400,9 @@ def f(x, y): nanne = make_nancomp(operator.ne) -def _nanpercentile_1d(values, mask, q, na_value, interpolation): +def _nanpercentile_1d( + values: np.ndarray, mask: np.ndarray, q, na_value: Scalar, interpolation: str +) -> Union[Scalar, np.ndarray]: """ Wrapper for np.percentile that skips missing values, specialized to 1-dimensional case. @@ -1366,7 +1433,15 @@ def _nanpercentile_1d(values, mask, q, na_value, interpolation): return np.percentile(values, q, interpolation=interpolation) -def nanpercentile(values, q, axis, na_value, mask, ndim, interpolation): +def nanpercentile( + values: np.ndarray, + q, + axis: int, + na_value, + mask: np.ndarray, + ndim: int, + interpolation: str, +): """ Wrapper for np.percentile that skips missing values. From 3f07a8fe6c45e353b95d671fe5cae14e33c882ad Mon Sep 17 00:00:00 2001 From: MomIsBestFriend <> Date: Sun, 29 Dec 2019 13:50:57 +0200 Subject: [PATCH 02/11] Fixes for jbrockmendel review --- pandas/core/nanops.py | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/pandas/core/nanops.py b/pandas/core/nanops.py index 2692948e8d329..c91262b24dd4e 100644 --- a/pandas/core/nanops.py +++ b/pandas/core/nanops.py @@ -167,7 +167,9 @@ def _has_infs(result) -> bool: def _get_fill_value( - dtype: Dtype, fill_value: Any = None, fill_value_typ: Optional[str] = None + dtype: Dtype, + fill_value: Optional[Scalar] = None, + fill_value_typ: Optional[str] = None, ): """ return the correct fill value for the dtype of the values """ if fill_value is not None: @@ -652,7 +654,7 @@ def _get_counts_nanvar( mask: Optional[np.ndarray], axis: Optional[int], ddof: int, - dtype: Dtype = float, + dtype=float, ) -> Tuple[Union[int, np.ndarray], Union[int, np.ndarray]]: """ Get the count of non-null values along an axis, accounting for degrees of freedom. @@ -1135,7 +1137,7 @@ def nanprod( skipna: bool = True, min_count: int = 0, mask: Optional[np.ndarray] = None, -) -> Dtype: +): """ Parameters ---------- @@ -1148,7 +1150,7 @@ def nanprod( Returns ------- - result : dtype + The product of all elements on a given axis. ( NaNs are treated as 1) Examples -------- @@ -1156,10 +1158,6 @@ def nanprod( >>> s = pd.Series([1, 2, 3, np.nan]) >>> nanops.nanprod(s) 6.0 - - Returns - ------- - The product of all elements on a given axis. ( NaNs are treated as 1) """ mask = _maybe_get_mask(values, skipna, mask) @@ -1305,8 +1303,9 @@ def nancorr( return f(a, b) -def get_corr_func(method: str): - if method in ["kendall", "spearman"]: +def get_corr_func(method) -> Callable: + if method in ["kendall", "spearman", "pearson"]: + import scipy.stats from scipy.stats import kendalltau, spearmanr elif callable(method): return method From 0b6b26fdd2da49de1d18953d879c41e3b720ff9a Mon Sep 17 00:00:00 2001 From: MomIsBestFriend <> Date: Sun, 29 Dec 2019 16:01:30 +0200 Subject: [PATCH 03/11] Added scipy to dep list of azure-macOS and azure-36-32bit --- ci/deps/azure-36-32bit.yaml | 1 + ci/deps/azure-macos-36.yaml | 1 + pandas/core/nanops.py | 1 - 3 files changed, 2 insertions(+), 1 deletion(-) diff --git a/ci/deps/azure-36-32bit.yaml b/ci/deps/azure-36-32bit.yaml index cf3fca307481f..fa294be78b731 100644 --- a/ci/deps/azure-36-32bit.yaml +++ b/ci/deps/azure-36-32bit.yaml @@ -18,6 +18,7 @@ dependencies: - numpy=1.14.* - python-dateutil - pytz=2017.2 + - scipy>=1.1 # see comment above - pip diff --git a/ci/deps/azure-macos-36.yaml b/ci/deps/azure-macos-36.yaml index f393ed84ecf63..ea0083d1c8308 100644 --- a/ci/deps/azure-macos-36.yaml +++ b/ci/deps/azure-macos-36.yaml @@ -26,6 +26,7 @@ dependencies: - pytables - python-dateutil==2.6.1 - pytz + - scipy>=1.1 - xarray - xlrd - xlsxwriter diff --git a/pandas/core/nanops.py b/pandas/core/nanops.py index c91262b24dd4e..bc3eacff468d8 100644 --- a/pandas/core/nanops.py +++ b/pandas/core/nanops.py @@ -1305,7 +1305,6 @@ def nancorr( def get_corr_func(method) -> Callable: if method in ["kendall", "spearman", "pearson"]: - import scipy.stats from scipy.stats import kendalltau, spearmanr elif callable(method): return method From cc210dbccfe320ae586dd411e47d4c689787bc9e Mon Sep 17 00:00:00 2001 From: MomIsBestFriend <> Date: Tue, 31 Dec 2019 14:02:08 +0200 Subject: [PATCH 04/11] Fixes for review --- pandas/core/nanops.py | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/pandas/core/nanops.py b/pandas/core/nanops.py index bc3eacff468d8..00896773d08ee 100644 --- a/pandas/core/nanops.py +++ b/pandas/core/nanops.py @@ -857,7 +857,7 @@ def reduction( axis: Optional[int] = None, skipna: bool = True, mask: Optional[np.ndarray] = None, - ) -> np.ndarray: + ) -> Dtype: values, mask, dtype, dtype_max, fill_value = _get_values( values, skipna, fill_value_typ=fill_value_typ, mask=mask @@ -1137,7 +1137,7 @@ def nanprod( skipna: bool = True, min_count: int = 0, mask: Optional[np.ndarray] = None, -): +) -> Dtype: """ Parameters ---------- @@ -1150,7 +1150,8 @@ def nanprod( Returns ------- - The product of all elements on a given axis. ( NaNs are treated as 1) + Dtype + The product of all elements on a given axis. ( NaNs are treated as 1) Examples -------- @@ -1242,7 +1243,13 @@ def _maybe_null_out( mask: Optional[np.ndarray], shape: Tuple, min_count: int = 1, -) -> np.ndarray: +) -> Dtype: + """ + Returns + ------- + Dtype + The product of all elements on a given axis. ( NaNs are treated as 1) + """ if mask is not None and axis is not None and getattr(result, "ndim", False): null_mask = (mask.shape[axis] - mask.sum(axis) - min_count) < 0 if np.any(null_mask): From ddd4861f14d19ba6dae9a95b1761dc7d82bc1c32 Mon Sep 17 00:00:00 2001 From: MomIsBestFriend <> Date: Tue, 31 Dec 2019 14:18:34 +0200 Subject: [PATCH 05/11] Added dtype annotation --- pandas/core/nanops.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pandas/core/nanops.py b/pandas/core/nanops.py index 00896773d08ee..e829731393f41 100644 --- a/pandas/core/nanops.py +++ b/pandas/core/nanops.py @@ -654,7 +654,7 @@ def _get_counts_nanvar( mask: Optional[np.ndarray], axis: Optional[int], ddof: int, - dtype=float, + dtype: Dtype = float, ) -> Tuple[Union[int, np.ndarray], Union[int, np.ndarray]]: """ Get the count of non-null values along an axis, accounting for degrees of freedom. From 074494e12c55a5de65eccfb81d698249280a646b Mon Sep 17 00:00:00 2001 From: MomIsBestFriend <> Date: Wed, 1 Jan 2020 15:29:13 +0200 Subject: [PATCH 06/11] Removed changes that are not typing related --- ci/deps/azure-36-32bit.yaml | 1 - ci/deps/azure-macos-36.yaml | 1 - pandas/core/nanops.py | 2 +- 3 files changed, 1 insertion(+), 3 deletions(-) diff --git a/ci/deps/azure-36-32bit.yaml b/ci/deps/azure-36-32bit.yaml index fa294be78b731..cf3fca307481f 100644 --- a/ci/deps/azure-36-32bit.yaml +++ b/ci/deps/azure-36-32bit.yaml @@ -18,7 +18,6 @@ dependencies: - numpy=1.14.* - python-dateutil - pytz=2017.2 - - scipy>=1.1 # see comment above - pip diff --git a/ci/deps/azure-macos-36.yaml b/ci/deps/azure-macos-36.yaml index ea0083d1c8308..f393ed84ecf63 100644 --- a/ci/deps/azure-macos-36.yaml +++ b/ci/deps/azure-macos-36.yaml @@ -26,7 +26,6 @@ dependencies: - pytables - python-dateutil==2.6.1 - pytz - - scipy>=1.1 - xarray - xlrd - xlsxwriter diff --git a/pandas/core/nanops.py b/pandas/core/nanops.py index e829731393f41..6bd7e2dbd287d 100644 --- a/pandas/core/nanops.py +++ b/pandas/core/nanops.py @@ -1311,7 +1311,7 @@ def nancorr( def get_corr_func(method) -> Callable: - if method in ["kendall", "spearman", "pearson"]: + if method in ["kendall", "spearman"]: from scipy.stats import kendalltau, spearmanr elif callable(method): return method From 5c2ecef4ea73bf43588072be383a86e38c14a718 Mon Sep 17 00:00:00 2001 From: MomIsBestFriend <> Date: Sun, 5 Jan 2020 09:46:39 +0200 Subject: [PATCH 07/11] Removed 'Dtype' as a return type --- pandas/core/nanops.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/pandas/core/nanops.py b/pandas/core/nanops.py index c7900ec4fa972..e5737f9efd2e5 100644 --- a/pandas/core/nanops.py +++ b/pandas/core/nanops.py @@ -483,7 +483,7 @@ def nansum( skipna: bool = True, min_count: int = 0, mask: Optional[np.ndarray] = None, -) -> Dtype: +) -> float: """ Sum the elements along an axis ignoring NaNs @@ -1137,7 +1137,7 @@ def nanprod( skipna: bool = True, min_count: int = 0, mask: Optional[np.ndarray] = None, -) -> Dtype: +) -> float: """ Parameters ---------- @@ -1243,7 +1243,7 @@ def _maybe_null_out( mask: Optional[np.ndarray], shape: Tuple, min_count: int = 1, -) -> Dtype: +) -> float: """ Returns ------- From 57d9502a98b2a4dbda5b92a3959ef28354549133 Mon Sep 17 00:00:00 2001 From: MomIsBestFriend <> Date: Tue, 14 Jan 2020 15:01:52 +0200 Subject: [PATCH 08/11] Reverted typing --- pandas/core/nanops.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pandas/core/nanops.py b/pandas/core/nanops.py index d8090cb58b222..85454e2950546 100644 --- a/pandas/core/nanops.py +++ b/pandas/core/nanops.py @@ -1286,7 +1286,7 @@ def _zero_out_fperr(arg): def nancorr( a: np.ndarray, b: np.ndarray, - method: str = "pearson", + method="pearson", min_periods: Optional[int] = None, ): """ From 6b55a1362affcbccc389d099965ec77c5ba50512 Mon Sep 17 00:00:00 2001 From: MomIsBestFriend <> Date: Tue, 14 Jan 2020 15:33:04 +0200 Subject: [PATCH 09/11] List issues --- pandas/core/nanops.py | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/pandas/core/nanops.py b/pandas/core/nanops.py index 85454e2950546..51c6d8be50653 100644 --- a/pandas/core/nanops.py +++ b/pandas/core/nanops.py @@ -1284,10 +1284,7 @@ def _zero_out_fperr(arg): @disallow("M8", "m8") def nancorr( - a: np.ndarray, - b: np.ndarray, - method="pearson", - min_periods: Optional[int] = None, + a: np.ndarray, b: np.ndarray, method="pearson", min_periods: Optional[int] = None, ): """ a, b: ndarrays From 328356467eb6d4b636a2e5acf696b059648ce5b5 Mon Sep 17 00:00:00 2001 From: MomIsBestFriend <> Date: Sat, 18 Jan 2020 23:50:09 +0200 Subject: [PATCH 10/11] Changed the name of "dt" to "dtype" Ref: https://github.com/pandas-dev/pandas/pull/30461#discussion_r368243516 --- pandas/core/nanops.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/pandas/core/nanops.py b/pandas/core/nanops.py index 51c6d8be50653..16843caf3f1a1 100644 --- a/pandas/core/nanops.py +++ b/pandas/core/nanops.py @@ -132,10 +132,10 @@ def f( return f -def _bn_ok_dtype(dt: Dtype, name: str) -> bool: +def _bn_ok_dtype(dtype: Dtype, name: str) -> bool: # Bottleneck chokes on datetime64 - if not is_object_dtype(dt) and not ( - is_datetime_or_timedelta_dtype(dt) or is_datetime64tz_dtype(dt) + if not is_object_dtype(dtype) and not ( + is_datetime_or_timedelta_dtype(dtype) or is_datetime64tz_dtype(dtype) ): # GH 15507 From 7442310a426f9160abab5e201c10b8ad4590b25d Mon Sep 17 00:00:00 2001 From: MomIsBestFriend <> Date: Sun, 19 Jan 2020 00:40:44 +0200 Subject: [PATCH 11/11] Removed any newly added annotation of Callable/str This is because no matter what typing annotation combination of "method" is being used "Union[Callable, str]" or "Callable" or "str" mypy is raising errors --- pandas/core/nanops.py | 22 ++++++++++------------ 1 file changed, 10 insertions(+), 12 deletions(-) diff --git a/pandas/core/nanops.py b/pandas/core/nanops.py index 16843caf3f1a1..2bf2be082f639 100644 --- a/pandas/core/nanops.py +++ b/pandas/core/nanops.py @@ -1,7 +1,7 @@ import functools import itertools import operator -from typing import Any, Callable, Optional, Tuple, Union +from typing import Any, Optional, Tuple, Union import numpy as np @@ -56,7 +56,7 @@ def __init__(self, *dtypes): def check(self, obj) -> bool: return hasattr(obj, "dtype") and issubclass(obj.dtype.type, self.dtypes) - def __call__(self, f) -> Callable: + def __call__(self, f): @functools.wraps(f) def _f(*args, **kwargs): obj_iter = itertools.chain(args, kwargs.values()) @@ -81,11 +81,11 @@ def _f(*args, **kwargs): class bottleneck_switch: - def __init__(self, name: Optional[str] = None, **kwargs): + def __init__(self, name=None, **kwargs): self.name = name self.kwargs = kwargs - def __call__(self, alt: Callable) -> Callable: + def __call__(self, alt): bn_name = self.name or alt.__name__ try: @@ -167,9 +167,7 @@ def _has_infs(result) -> bool: def _get_fill_value( - dtype: Dtype, - fill_value: Optional[Scalar] = None, - fill_value_typ: Optional[str] = None, + dtype: Dtype, fill_value: Optional[Scalar] = None, fill_value_typ=None ): """ return the correct fill value for the dtype of the values """ if fill_value is not None: @@ -850,7 +848,7 @@ def nansem( return np.sqrt(var) / np.sqrt(count) -def _nanminmax(meth: str, fill_value_typ: str) -> Callable: +def _nanminmax(meth, fill_value_typ): @bottleneck_switch(name="nan" + meth) def reduction( values: np.ndarray, @@ -1307,7 +1305,7 @@ def nancorr( return f(a, b) -def get_corr_func(method) -> Callable: +def get_corr_func(method): if method in ["kendall", "spearman"]: from scipy.stats import kendalltau, spearmanr elif method in ["pearson"]: @@ -1381,7 +1379,7 @@ def _ensure_numeric(x): # NA-friendly array comparisons -def make_nancomp(op) -> Callable: +def make_nancomp(op): def f(x, y): xmask = isna(x) ymask = isna(y) @@ -1409,7 +1407,7 @@ def f(x, y): def _nanpercentile_1d( - values: np.ndarray, mask: np.ndarray, q, na_value: Scalar, interpolation: str + values: np.ndarray, mask: np.ndarray, q, na_value: Scalar, interpolation ) -> Union[Scalar, np.ndarray]: """ Wrapper for np.percentile that skips missing values, specialized to @@ -1448,7 +1446,7 @@ def nanpercentile( na_value, mask: np.ndarray, ndim: int, - interpolation: str, + interpolation, ): """ Wrapper for np.percentile that skips missing values.