diff --git a/dios/indexer.py b/dios/indexer.py index a2b0c6f34e798b657d64c7ea398f9d5df9e5ab9e..4b10a52abdadcd319efd35c2f7dcccb49d25131d 100644 --- a/dios/indexer.py +++ b/dios/indexer.py @@ -18,6 +18,7 @@ _is_dict_like = dcom.is_dict_like _is_number = dcom.is_number _is_hashable = dcom.is_hashable _is_bool_indexer = ccom.is_bool_indexer +_is_null_slice = ccom.is_null_slice class _Indexer: @@ -112,6 +113,10 @@ class _LocIndexer(_Indexer): if _is_dios_like(rowkey) or _is_dios_like(colkey): raise ValueError("Could not index with multidimensional key") + # simple optimisation + if _is_null_slice(rowkey) and _is_null_slice(colkey): + return self.obj.copy() + data = self._data.loc[colkey].copy() # .loc[any, scalar] -> (a single) series @@ -180,6 +185,10 @@ class _iLocIndexer(_Indexer): if _is_dios_like(rowkey) or _is_dios_like(colkey): raise ValueError("Cannot index with multidimensional key") + # simple optimisation + if _is_null_slice(rowkey) and _is_null_slice(colkey): + return self.obj.copy() + data = self._data.iloc[colkey].copy() # .iloc[any, int] -> single series @@ -240,7 +249,7 @@ class _aLocIndexer(_Indexer): """ align Indexer Automatically align (alignable) indexer on all possible axis, - and handle indexing with non-existent or missing keys gratefully. + and handle indexing with non-existent or missing keys gracefully. Also align (alignable) values before setting them with .loc """ @@ -390,7 +399,7 @@ class _aLocIndexer(_Indexer): elif _is_dios_like(colkey) or _is_nested_list_like(colkey): raise ValueError("Could not index with multi-dimensional column key.") - # handle gratefully: scalar + # handle gracefully: scalar if _is_hashable(colkey): colkey = [colkey] if colkey in self.obj.columns else [] lowdim = True @@ -400,6 +409,11 @@ class _aLocIndexer(_Indexer): colkey = colkey.values if isinstance(colkey, pd.Series) else colkey colkey = self.obj.columns.intersection(colkey) + # handle gracefully (automatically) + # just a simple optimisation + elif _is_null_slice(colkey): + colkey = self.obj.columns + # not alignable, fall back to .loc (boolean list/series, slice(..), etc. else: colkey = self._data.loc[colkey].index @@ -414,11 +428,11 @@ class _aLocIndexer(_Indexer): if isinstance(rowkey, pd.Series): rowkey = [self._data.at[c].index.intersection(rowkey.index) for c in colkey] - # handle gratefully: scalar, transform to row-slice + # handle gracefully: scalar, transform to row-slice elif _is_hashable(rowkey): rowkey = [slice(rowkey, rowkey)] * len(colkey) - # handle gratefully: list-like, filter only existing rows + # handle gracefully: list-like, filter only existing rows # NOTE: dios.aloc[series.index] is processed here elif _is_list_like(rowkey) and not _is_bool_indexer(rowkey): rowkey = [self._data.at[c].index.intersection(rowkey) for c in colkey]