diff --git a/pandas/core/internals/__init__.py b/pandas/core/internals/__init__.py index 7d6aa6a42efc2..7878613a8b1b1 100644 --- a/pandas/core/internals/__init__.py +++ b/pandas/core/internals/__init__.py @@ -5,8 +5,7 @@ make_block, # io.pytables, io.packers FloatBlock, IntBlock, ComplexBlock, BoolBlock, ObjectBlock, TimeDeltaBlock, DatetimeBlock, DatetimeTZBlock, - CategoricalBlock, ExtensionBlock, ScalarBlock, - Block) + CategoricalBlock, ExtensionBlock, Block) from .managers import ( # noqa:F401 BlockManager, SingleBlockManager, create_block_manager_from_arrays, create_block_manager_from_blocks, diff --git a/pandas/core/internals/blocks.py b/pandas/core/internals/blocks.py index 384676ede15f2..f88114e1c9e20 100644 --- a/pandas/core/internals/blocks.py +++ b/pandas/core/internals/blocks.py @@ -222,12 +222,6 @@ def make_block(self, values, placement=None, ndim=None): return make_block(values, placement=placement, ndim=ndim) - def make_block_scalar(self, values): - """ - Create a ScalarBlock - """ - return ScalarBlock(values) - def make_block_same_class(self, values, placement=None, ndim=None, dtype=None): """ Wrap given values in a block of same type as self. """ @@ -1468,13 +1462,15 @@ def quantile(self, qs, interpolation='linear', axis=0): else: # create the array of na_values # 2d len(values) * len(qs) - result = np.repeat(np.array([self._na_value] * len(qs)), + result = np.repeat(np.array([self.fill_value] * len(qs)), len(values)).reshape(len(values), len(qs)) else: - mask = isna(self.values) + # asarray needed for Sparse, see GH#24600 + # TODO: Why self.values and not values? + mask = np.asarray(isna(self.values)) result = nanpercentile(values, np.array(qs) * 100, - axis=axis, na_value=self._na_value, + axis=axis, na_value=self.fill_value, mask=mask, ndim=self.ndim, interpolation=interpolation) @@ -1490,8 +1486,6 @@ def quantile(self, qs, interpolation='linear', axis=0): ndim = getattr(result, 'ndim', None) or 0 result = self._try_coerce_result(result) - if lib.is_scalar(result): - return self.make_block_scalar(result) return make_block(result, placement=np.arange(len(result)), ndim=ndim) @@ -1534,29 +1528,6 @@ def _replace_coerce(self, to_replace, value, inplace=True, regex=False, return self -class ScalarBlock(Block): - """ - a scalar compat Block - """ - __slots__ = ['_mgr_locs', 'values', 'ndim'] - - def __init__(self, values): - self.ndim = 0 - self.mgr_locs = [0] - self.values = values - - @property - def dtype(self): - return type(self.values) - - @property - def shape(self): - return tuple([0]) - - def __len__(self): - return 0 - - class NonConsolidatableMixIn(object): """ hold methods for the nonconsolidatable blocks """ _can_consolidate = False @@ -2675,7 +2646,7 @@ def convert(self, *args, **kwargs): if args: raise NotImplementedError - by_item = True if 'by_item' not in kwargs else kwargs['by_item'] + by_item = kwargs.get('by_item', True) new_inputs = ['coerce', 'datetime', 'numeric', 'timedelta'] new_style = False diff --git a/pandas/core/internals/managers.py b/pandas/core/internals/managers.py index 0ad0a994e8a95..ab033ff4c1c4b 100644 --- a/pandas/core/internals/managers.py +++ b/pandas/core/internals/managers.py @@ -425,6 +425,10 @@ def quantile(self, axis=0, consolidate=True, transposed=False, Block Manager (new object) """ + # Series dispatches to DataFrame for quantile, which allows us to + # simplify some of the code here and in the blocks + assert self.ndim >= 2 + if consolidate: self._consolidate_inplace() @@ -449,6 +453,7 @@ def get_axe(block, qs, axes): # note that some DatetimeTZ, Categorical are always ndim==1 ndim = {b.ndim for b in blocks} + assert 0 not in ndim, ndim if 2 in ndim: @@ -474,15 +479,7 @@ def get_axe(block, qs, axes): return self.__class__(blocks, new_axes) - # 0 ndim - if 0 in ndim and 1 not in ndim: - values = np.array([b.values for b in blocks]) - if len(values) == 1: - return values.item() - blocks = [make_block(values, ndim=1)] - axes = Index([ax[0] for ax in axes]) - - # single block + # single block, i.e. ndim == {1} values = _concat._concat_compat([b.values for b in blocks]) # compute the orderings of our original data diff --git a/pandas/core/series.py b/pandas/core/series.py index 46ff04fdd31ae..de34227cda28a 100644 --- a/pandas/core/series.py +++ b/pandas/core/series.py @@ -1987,15 +1987,23 @@ def quantile(self, q=0.5, interpolation='linear'): self._check_percentile(q) - result = self._data.quantile(qs=q, interpolation=interpolation) + # We dispatch to DataFrame so that core.internals only has to worry + # about 2D cases. + df = self.to_frame() + + result = df.quantile(q=q, interpolation=interpolation, + numeric_only=False) + if result.ndim == 2: + result = result.iloc[:, 0] if is_list_like(q): + result.name = self.name return self._constructor(result, index=Float64Index(q), name=self.name) else: # scalar - return result + return result.iloc[0] def corr(self, other, method='pearson', min_periods=None): """ diff --git a/pandas/tests/resample/test_base.py b/pandas/tests/resample/test_base.py index 31199dc01b659..0efd48c25ad62 100644 --- a/pandas/tests/resample/test_base.py +++ b/pandas/tests/resample/test_base.py @@ -218,5 +218,5 @@ def test_resample_quantile_all_ts(series): q = 0.75 freq = 'H' result = s.resample(freq).quantile(q) - expected = s.resample(freq).agg(lambda x: x.quantile(q)) + expected = s.resample(freq).agg(lambda x: x.quantile(q)).rename(s.name) tm.assert_series_equal(result, expected)