Ensure that a slice doesn't reduce to a Series or Scalar. Any user-passed `subset` should have this called on it to make sure we're always working with DataFrames.
(slice_: Subset)
| 2020 | |
| 2021 | |
| 2022 | def non_reducing_slice(slice_: Subset): |
| 2023 | """ |
| 2024 | Ensure that a slice doesn't reduce to a Series or Scalar. |
| 2025 | |
| 2026 | Any user-passed `subset` should have this called on it |
| 2027 | to make sure we're always working with DataFrames. |
| 2028 | """ |
| 2029 | # default to column slice, like DataFrame |
| 2030 | # ['A', 'B'] -> IndexSlices[:, ['A', 'B']] |
| 2031 | kinds = (ABCSeries, np.ndarray, Index, list, str) |
| 2032 | if isinstance(slice_, kinds): |
| 2033 | slice_ = IndexSlice[:, slice_] |
| 2034 | |
| 2035 | def pred(part) -> bool: |
| 2036 | """ |
| 2037 | Returns |
| 2038 | ------- |
| 2039 | bool |
| 2040 | True if slice does *not* reduce, |
| 2041 | False if `part` is a tuple. |
| 2042 | """ |
| 2043 | # true when slice does *not* reduce, False when part is a tuple, |
| 2044 | # i.e. MultiIndex slice |
| 2045 | if isinstance(part, tuple): |
| 2046 | # GH#39421 check for sub-slice: |
| 2047 | return any((isinstance(s, slice) or is_list_like(s)) for s in part) |
| 2048 | else: |
| 2049 | return isinstance(part, slice) or is_list_like(part) |
| 2050 | |
| 2051 | if not is_list_like(slice_): |
| 2052 | if not isinstance(slice_, slice): |
| 2053 | # a 1-d slice, like df.loc[1] |
| 2054 | slice_ = [[slice_]] |
| 2055 | else: |
| 2056 | # slice(a, b, c) |
| 2057 | slice_ = [slice_] # to tuplize later |
| 2058 | else: |
| 2059 | # error: Item "slice" of "Union[slice, Sequence[Any]]" has no attribute |
| 2060 | # "__iter__" (not iterable) -> is specifically list_like in conditional |
| 2061 | slice_ = [p if pred(p) else [p] for p in slice_] # type: ignore[union-attr] |
| 2062 | return tuple(slice_) |
| 2063 | |
| 2064 | |
| 2065 | def maybe_convert_css_to_tuples(style: CSSProperties) -> CSSList: |