diff --git a/pandas/_libs/missing.pyx b/pandas/_libs/missing.pyx index 1d756115ebd5a..052b081988c9e 100644 --- a/pandas/_libs/missing.pyx +++ b/pandas/_libs/missing.pyx @@ -80,11 +80,8 @@ cpdef bint checknull_old(object val): cdef inline bint _check_none_nan_inf_neginf(object val): - try: - return val is None or (isinstance(val, float) and - (val != val or val == INF or val == NEGINF)) - except ValueError: - return False + return val is None or (isinstance(val, float) and + (val != val or val == INF or val == NEGINF)) @cython.wraparound(False) diff --git a/pandas/core/arrays/categorical.py b/pandas/core/arrays/categorical.py index 6200cd14663f8..dd71daab9d4c5 100644 --- a/pandas/core/arrays/categorical.py +++ b/pandas/core/arrays/categorical.py @@ -38,12 +38,7 @@ is_timedelta64_dtype, ) from pandas.core.dtypes.dtypes import CategoricalDtype -from pandas.core.dtypes.generic import ( - ABCCategoricalIndex, - ABCDataFrame, - ABCIndexClass, - ABCSeries, -) +from pandas.core.dtypes.generic import ABCDataFrame, ABCIndexClass, ABCSeries from pandas.core.dtypes.inference import is_hashable from pandas.core.dtypes.missing import isna, notna @@ -166,19 +161,6 @@ def f(self, other): return f -def _maybe_to_categorical(array): - """ - Coerce to a categorical if a series is given. - - Internal use ONLY. - """ - if isinstance(array, (ABCSeries, ABCCategoricalIndex)): - return array._values - elif isinstance(array, np.ndarray): - return Categorical(array) - return array - - def contains(cat, key, container): """ Helper for membership check for ``key`` in ``cat``. @@ -1988,23 +1970,6 @@ def take_nd(self, indexer, allow_fill=None, fill_value=None): take = take_nd - def _slice(self, slicer): - """ - Return a slice of myself. - - For internal compatibility with numpy arrays. - """ - - # only allow 1 dimensional slicing, but can - # in a 2-d case be passd (slice(None),....) - if isinstance(slicer, tuple) and len(slicer) == 2: - if not com.is_null_slice(slicer[0]): - raise AssertionError("invalid slicing for a 1-ndim " "categorical") - slicer = slicer[1] - - codes = self._codes[slicer] - return self._constructor(values=codes, dtype=self.dtype, fastpath=True) - def __len__(self): """ The length of this Categorical. diff --git a/pandas/core/arrays/sparse.py b/pandas/core/arrays/sparse.py index 9376b49112f6f..ee3652a211e31 100644 --- a/pandas/core/arrays/sparse.py +++ b/pandas/core/arrays/sparse.py @@ -601,10 +601,6 @@ def __init__( dtype=None, copy=False, ): - from pandas.core.internals import SingleBlockManager - - if isinstance(data, SingleBlockManager): - data = data.internal_values() if fill_value is None and isinstance(dtype, SparseDtype): fill_value = dtype.fill_value @@ -1859,15 +1855,6 @@ def _formatter(self, boxed=False): SparseArray._add_unary_ops() -def _maybe_to_dense(obj): - """ - try to convert to dense - """ - if hasattr(obj, "to_dense"): - return obj.to_dense() - return obj - - def make_sparse(arr, kind="block", fill_value=None, dtype=None, copy=False): """ Convert ndarray to sparse format diff --git a/pandas/core/generic.py b/pandas/core/generic.py index 9053edf2d1424..1a854af52c20e 100644 --- a/pandas/core/generic.py +++ b/pandas/core/generic.py @@ -4892,12 +4892,12 @@ def sample( if weights is not None: # If a series, align with frame - if isinstance(weights, pd.Series): + if isinstance(weights, ABCSeries): weights = weights.reindex(self.axes[axis]) # Strings acceptable if a dataframe and axis = 0 if isinstance(weights, str): - if isinstance(self, pd.DataFrame): + if isinstance(self, ABCDataFrame): if axis == 0: try: weights = self[weights] @@ -6628,7 +6628,7 @@ def replace( to_replace = [to_replace] if isinstance(to_replace, (tuple, list)): - if isinstance(self, pd.DataFrame): + if isinstance(self, ABCDataFrame): return self.apply( _single_replace, args=(to_replace, method, inplace, limit) ) @@ -7421,7 +7421,7 @@ def _clip_with_one_bound(self, threshold, method, axis, inplace): # be transformed to NDFrame from other array like structure. if (not isinstance(threshold, ABCSeries)) and is_list_like(threshold): if isinstance(self, ABCSeries): - threshold = pd.Series(threshold, index=self.index) + threshold = self._constructor(threshold, index=self.index) else: threshold = _align_method_FRAME(self, threshold, axis) return self.where(subset, threshold, axis=axis, inplace=inplace) @@ -7510,9 +7510,9 @@ def clip(self, lower=None, upper=None, axis=None, inplace=False, *args, **kwargs # so ignore # GH 19992 # numpy doesn't drop a list-like bound containing NaN - if not is_list_like(lower) and np.any(pd.isnull(lower)): + if not is_list_like(lower) and np.any(isna(lower)): lower = None - if not is_list_like(upper) and np.any(pd.isnull(upper)): + if not is_list_like(upper) and np.any(isna(upper)): upper = None # GH 2747 (arguments were reversed) @@ -8985,7 +8985,7 @@ def _where( msg = "Boolean array expected for the condition, not {dtype}" - if not isinstance(cond, pd.DataFrame): + if not isinstance(cond, ABCDataFrame): # This is a single-dimensional object. if not is_bool_dtype(cond): raise ValueError(msg.format(dtype=cond.dtype)) diff --git a/pandas/core/groupby/generic.py b/pandas/core/groupby/generic.py index 5b9cec6903749..b886b7e305ed0 100644 --- a/pandas/core/groupby/generic.py +++ b/pandas/core/groupby/generic.py @@ -35,7 +35,7 @@ is_object_dtype, is_scalar, ) -from pandas.core.dtypes.missing import isna, notna +from pandas.core.dtypes.missing import _isna_ndarraylike, isna, notna from pandas._typing import FrameOrSeries import pandas.core.algorithms as algorithms @@ -44,8 +44,13 @@ from pandas.core.frame import DataFrame from pandas.core.generic import ABCDataFrame, ABCSeries, NDFrame, _shared_docs from pandas.core.groupby import base -from pandas.core.groupby.groupby import GroupBy, _apply_docs, _transform_template -from pandas.core.index import Index, MultiIndex +from pandas.core.groupby.groupby import ( + GroupBy, + _apply_docs, + _transform_template, + groupby, +) +from pandas.core.index import Index, MultiIndex, _all_indexes_same import pandas.core.indexes.base as ibase from pandas.core.internals import BlockManager, make_block from pandas.core.series import Series @@ -162,8 +167,6 @@ def _cython_agg_blocks(self, how, alt=None, numeric_only=True, min_count=-1): continue # call our grouper again with only this block - from pandas.core.groupby.groupby import groupby - obj = self.obj[data.items[locs]] s = groupby(obj, self.grouper) try: @@ -348,8 +351,6 @@ def _decide_output_index(self, output, labels): return output_keys def _wrap_applied_output(self, keys, values, not_indexed_same=False): - from pandas.core.index import _all_indexes_same - if len(keys) == 0: return DataFrame(index=keys) @@ -1590,13 +1591,14 @@ def count(self): DataFrame Count of values within each group. """ - from pandas.core.dtypes.missing import _isna_ndarraylike as _isna - data, _ = self._get_data_to_aggregate() ids, _, ngroups = self.grouper.group_info mask = ids != -1 - val = ((mask & ~_isna(np.atleast_2d(blk.get_values()))) for blk in data.blocks) + val = ( + (mask & ~_isna_ndarraylike(np.atleast_2d(blk.get_values()))) + for blk in data.blocks + ) loc = (blk.mgr_locs for blk in data.blocks) counter = partial(lib.count_level_2d, labels=ids, max_bin=ngroups, axis=1) diff --git a/pandas/core/internals/blocks.py b/pandas/core/internals/blocks.py index 549920e230e8a..75dbe74c897f4 100644 --- a/pandas/core/internals/blocks.py +++ b/pandas/core/internals/blocks.py @@ -3074,10 +3074,10 @@ class CategoricalBlock(ExtensionBlock): _concatenator = staticmethod(concat_categorical) def __init__(self, values, placement, ndim=None): - from pandas.core.arrays.categorical import _maybe_to_categorical - # coerce to categorical if we can - super().__init__(_maybe_to_categorical(values), placement=placement, ndim=ndim) + values = extract_array(values) + assert isinstance(values, Categorical), type(values) + super().__init__(values, placement=placement, ndim=ndim) @property def _holder(self): diff --git a/pandas/core/reshape/pivot.py b/pandas/core/reshape/pivot.py index 2bdef766a3434..79716520f6654 100644 --- a/pandas/core/reshape/pivot.py +++ b/pandas/core/reshape/pivot.py @@ -127,8 +127,6 @@ def pivot_table( table = agged.unstack(to_unstack) if not dropna: - from pandas import MultiIndex - if table.index.nlevels > 1: m = MultiIndex.from_arrays( cartesian_product(table.index.levels), names=table.index.names diff --git a/pandas/core/sorting.py b/pandas/core/sorting.py index 5f3ed87424d0e..1ab6c792c6402 100644 --- a/pandas/core/sorting.py +++ b/pandas/core/sorting.py @@ -202,19 +202,19 @@ def lexsort_indexer(keys, orders=None, na_position="last"): # we are already a Categorical if is_categorical_dtype(key): - c = key + cat = key # create the Categorical else: - c = Categorical(key, ordered=True) + cat = Categorical(key, ordered=True) if na_position not in ["last", "first"]: raise ValueError("invalid na_position: {!r}".format(na_position)) - n = len(c.categories) - codes = c.codes.copy() + n = len(cat.categories) + codes = cat.codes.copy() - mask = c.codes == -1 + mask = cat.codes == -1 if order: # ascending if na_position == "last": codes = np.where(mask, n, codes) diff --git a/pandas/core/sparse/series.py b/pandas/core/sparse/series.py index f5d39c47150a2..0bd20e75d17ec 100644 --- a/pandas/core/sparse/series.py +++ b/pandas/core/sparse/series.py @@ -114,6 +114,11 @@ def __init__( elif is_scalar(data) and index is not None: data = np.full(len(index), fill_value=data) + if isinstance(data, SingleBlockManager): + # SparseArray doesn't accept SingleBlockManager + index = data.index + data = data.blocks[0].values + super().__init__( SparseArray( data, diff --git a/pandas/core/window.py b/pandas/core/window.py index 5098ab3c7220f..14d109ccf6a9c 100644 --- a/pandas/core/window.py +++ b/pandas/core/window.py @@ -40,6 +40,7 @@ import pandas.core.common as com from pandas.core.generic import _shared_docs from pandas.core.groupby.base import GroupByMixin +from pandas.core.index import Index, MultiIndex, ensure_index _shared_docs = dict(**_shared_docs) _doc_template = """ @@ -281,7 +282,6 @@ def _wrap_results(self, results, blocks, obj, exclude=None) -> FrameOrSeries: """ from pandas import Series, concat - from pandas.core.index import ensure_index final = [] for result, block in zip(results, blocks): @@ -1691,8 +1691,6 @@ def _on(self): if self.on is None: return self.obj.index elif isinstance(self.obj, ABCDataFrame) and self.on in self.obj.columns: - from pandas import Index - return Index(self.obj[self.on]) else: raise ValueError( @@ -2670,7 +2668,7 @@ def dataframe_from_int_dict(data, frame_template): *_prep_binary(arg1.iloc[:, i], arg2.iloc[:, j]) ) - from pandas import MultiIndex, concat + from pandas import concat result_index = arg1.index.union(arg2.index) if len(result_index):