Skip to content

Commit 68fe64b

Browse files
authored
CLN: remove redundant code related to Styler (#39884)
1 parent 23d8c1c commit 68fe64b

File tree

5 files changed

+141
-171
lines changed

5 files changed

+141
-171
lines changed

pandas/core/indexing.py

-54
Original file line numberDiff line numberDiff line change
@@ -2403,57 +2403,3 @@ def need_slice(obj) -> bool:
24032403
or obj.stop is not None
24042404
or (obj.step is not None and obj.step != 1)
24052405
)
2406-
2407-
2408-
def non_reducing_slice(slice_):
2409-
"""
2410-
Ensure that a slice doesn't reduce to a Series or Scalar.
2411-
2412-
Any user-passed `subset` should have this called on it
2413-
to make sure we're always working with DataFrames.
2414-
"""
2415-
# default to column slice, like DataFrame
2416-
# ['A', 'B'] -> IndexSlices[:, ['A', 'B']]
2417-
kinds = (ABCSeries, np.ndarray, Index, list, str)
2418-
if isinstance(slice_, kinds):
2419-
slice_ = IndexSlice[:, slice_]
2420-
2421-
def pred(part) -> bool:
2422-
"""
2423-
Returns
2424-
-------
2425-
bool
2426-
True if slice does *not* reduce,
2427-
False if `part` is a tuple.
2428-
"""
2429-
# true when slice does *not* reduce, False when part is a tuple,
2430-
# i.e. MultiIndex slice
2431-
if isinstance(part, tuple):
2432-
# GH#39421 check for sub-slice:
2433-
return any((isinstance(s, slice) or is_list_like(s)) for s in part)
2434-
else:
2435-
return isinstance(part, slice) or is_list_like(part)
2436-
2437-
if not is_list_like(slice_):
2438-
if not isinstance(slice_, slice):
2439-
# a 1-d slice, like df.loc[1]
2440-
slice_ = [[slice_]]
2441-
else:
2442-
# slice(a, b, c)
2443-
slice_ = [slice_] # to tuplize later
2444-
else:
2445-
slice_ = [part if pred(part) else [part] for part in slice_]
2446-
return tuple(slice_)
2447-
2448-
2449-
def maybe_numeric_slice(df, slice_, include_bool: bool = False):
2450-
"""
2451-
Want nice defaults for background_gradient that don't break
2452-
with non-numeric data. But if slice_ is passed go with that.
2453-
"""
2454-
if slice_ is None:
2455-
dtypes = [np.number]
2456-
if include_bool:
2457-
dtypes.append(bool)
2458-
slice_ = IndexSlice[:, df.select_dtypes(include=dtypes).columns]
2459-
return slice_

pandas/io/formats/style.py

+53-12
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@
3737
from pandas.util._decorators import doc
3838

3939
from pandas.core.dtypes.common import is_float
40+
from pandas.core.dtypes.generic import ABCSeries
4041

4142
import pandas as pd
4243
from pandas.api.types import (
@@ -47,10 +48,7 @@
4748
import pandas.core.common as com
4849
from pandas.core.frame import DataFrame
4950
from pandas.core.generic import NDFrame
50-
from pandas.core.indexing import (
51-
maybe_numeric_slice,
52-
non_reducing_slice,
53-
)
51+
from pandas.core.indexes.api import Index
5452

5553
jinja2 = import_optional_dependency("jinja2", extra="DataFrame.style requires jinja2.")
5654

@@ -624,7 +622,7 @@ def format(self, formatter, subset=None, na_rep: Optional[str] = None) -> Styler
624622
row_locs = range(len(self.data))
625623
col_locs = range(len(self.data.columns))
626624
else:
627-
subset = non_reducing_slice(subset)
625+
subset = _non_reducing_slice(subset)
628626
if len(subset) == 1:
629627
subset = subset, self.data.columns
630628

@@ -838,7 +836,7 @@ def _apply(
838836
**kwargs,
839837
) -> Styler:
840838
subset = slice(None) if subset is None else subset
841-
subset = non_reducing_slice(subset)
839+
subset = _non_reducing_slice(subset)
842840
data = self.data.loc[subset]
843841
if axis is not None:
844842
result = data.apply(func, axis=axis, result_type="expand", **kwargs)
@@ -941,7 +939,7 @@ def _applymap(self, func: Callable, subset=None, **kwargs) -> Styler:
941939
func = partial(func, **kwargs) # applymap doesn't take kwargs?
942940
if subset is None:
943941
subset = pd.IndexSlice[:]
944-
subset = non_reducing_slice(subset)
942+
subset = _non_reducing_slice(subset)
945943
result = self.data.loc[subset].applymap(func)
946944
self._update_ctx(result)
947945
return self
@@ -1291,7 +1289,7 @@ def hide_columns(self, subset) -> Styler:
12911289
-------
12921290
self : Styler
12931291
"""
1294-
subset = non_reducing_slice(subset)
1292+
subset = _non_reducing_slice(subset)
12951293
hidden_df = self.data.loc[subset]
12961294
self.hidden_columns = self.columns.get_indexer_for(hidden_df.columns)
12971295
return self
@@ -1366,8 +1364,9 @@ def background_gradient(
13661364
of the data is extended by ``low * (x.max() - x.min())`` and ``high *
13671365
(x.max() - x.min())`` before normalizing.
13681366
"""
1369-
subset = maybe_numeric_slice(self.data, subset)
1370-
subset = non_reducing_slice(subset)
1367+
if subset is None:
1368+
subset = self.data.select_dtypes(include=np.number).columns
1369+
13711370
self.apply(
13721371
self._background_gradient,
13731372
cmap=cmap,
@@ -1600,8 +1599,9 @@ def bar(
16001599
"(eg: color=['#d65f5f', '#5fba7d'])"
16011600
)
16021601

1603-
subset = maybe_numeric_slice(self.data, subset)
1604-
subset = non_reducing_slice(subset)
1602+
if subset is None:
1603+
subset = self.data.select_dtypes(include=np.number).columns
1604+
16051605
self.apply(
16061606
self._bar,
16071607
subset=subset,
@@ -2075,3 +2075,44 @@ def _maybe_convert_css_to_tuples(style: CSSProperties) -> CSSList:
20752075
f"for example 'attr: val;'. '{style}' was given."
20762076
)
20772077
return style
2078+
2079+
2080+
def _non_reducing_slice(slice_):
2081+
"""
2082+
Ensure that a slice doesn't reduce to a Series or Scalar.
2083+
2084+
Any user-passed `subset` should have this called on it
2085+
to make sure we're always working with DataFrames.
2086+
"""
2087+
# default to column slice, like DataFrame
2088+
# ['A', 'B'] -> IndexSlices[:, ['A', 'B']]
2089+
kinds = (ABCSeries, np.ndarray, Index, list, str)
2090+
if isinstance(slice_, kinds):
2091+
slice_ = pd.IndexSlice[:, slice_]
2092+
2093+
def pred(part) -> bool:
2094+
"""
2095+
Returns
2096+
-------
2097+
bool
2098+
True if slice does *not* reduce,
2099+
False if `part` is a tuple.
2100+
"""
2101+
# true when slice does *not* reduce, False when part is a tuple,
2102+
# i.e. MultiIndex slice
2103+
if isinstance(part, tuple):
2104+
# GH#39421 check for sub-slice:
2105+
return any((isinstance(s, slice) or is_list_like(s)) for s in part)
2106+
else:
2107+
return isinstance(part, slice) or is_list_like(part)
2108+
2109+
if not is_list_like(slice_):
2110+
if not isinstance(slice_, slice):
2111+
# a 1-d slice, like df.loc[1]
2112+
slice_ = [[slice_]]
2113+
else:
2114+
# slice(a, b, c)
2115+
slice_ = [slice_] # to tuplize later
2116+
else:
2117+
slice_ = [part if pred(part) else [part] for part in slice_]
2118+
return tuple(slice_)

pandas/tests/indexing/multiindex/test_slice.py

-54
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@
1212
Timestamp,
1313
)
1414
import pandas._testing as tm
15-
from pandas.core.indexing import non_reducing_slice
1615
from pandas.tests.indexing.common import _mklbl
1716

1817

@@ -769,59 +768,6 @@ def test_int_series_slicing(self, multiindex_year_month_day_dataframe_random_dat
769768
expected = ymd.reindex(s.index[5:])
770769
tm.assert_frame_equal(result, expected)
771770

772-
def test_non_reducing_slice_on_multiindex(self):
773-
# GH 19861
774-
dic = {
775-
("a", "d"): [1, 4],
776-
("a", "c"): [2, 3],
777-
("b", "c"): [3, 2],
778-
("b", "d"): [4, 1],
779-
}
780-
df = DataFrame(dic, index=[0, 1])
781-
idx = pd.IndexSlice
782-
slice_ = idx[:, idx["b", "d"]]
783-
tslice_ = non_reducing_slice(slice_)
784-
785-
result = df.loc[tslice_]
786-
expected = DataFrame({("b", "d"): [4, 1]})
787-
tm.assert_frame_equal(result, expected)
788-
789-
@pytest.mark.parametrize(
790-
"slice_",
791-
[
792-
pd.IndexSlice[:, :],
793-
# check cols
794-
pd.IndexSlice[:, pd.IndexSlice[["a"]]], # inferred deeper need list
795-
pd.IndexSlice[:, pd.IndexSlice[["a"], ["c"]]], # inferred deeper need list
796-
pd.IndexSlice[:, pd.IndexSlice["a", "c", :]],
797-
pd.IndexSlice[:, pd.IndexSlice["a", :, "e"]],
798-
pd.IndexSlice[:, pd.IndexSlice[:, "c", "e"]],
799-
pd.IndexSlice[:, pd.IndexSlice["a", ["c", "d"], :]], # check list
800-
pd.IndexSlice[:, pd.IndexSlice["a", ["c", "d", "-"], :]], # allow missing
801-
pd.IndexSlice[:, pd.IndexSlice["a", ["c", "d", "-"], "e"]], # no slice
802-
# check rows
803-
pd.IndexSlice[pd.IndexSlice[["U"]], :], # inferred deeper need list
804-
pd.IndexSlice[pd.IndexSlice[["U"], ["W"]], :], # inferred deeper need list
805-
pd.IndexSlice[pd.IndexSlice["U", "W", :], :],
806-
pd.IndexSlice[pd.IndexSlice["U", :, "Y"], :],
807-
pd.IndexSlice[pd.IndexSlice[:, "W", "Y"], :],
808-
pd.IndexSlice[pd.IndexSlice[:, "W", ["Y", "Z"]], :], # check list
809-
pd.IndexSlice[pd.IndexSlice[:, "W", ["Y", "Z", "-"]], :], # allow missing
810-
pd.IndexSlice[pd.IndexSlice["U", "W", ["Y", "Z", "-"]], :], # no slice
811-
# check simultaneous
812-
pd.IndexSlice[pd.IndexSlice[:, "W", "Y"], pd.IndexSlice["a", "c", :]],
813-
],
814-
)
815-
def test_non_reducing_multi_slice_on_multiindex(self, slice_):
816-
# GH 33562
817-
cols = pd.MultiIndex.from_product([["a", "b"], ["c", "d"], ["e", "f"]])
818-
idxs = pd.MultiIndex.from_product([["U", "V"], ["W", "X"], ["Y", "Z"]])
819-
df = DataFrame(np.arange(64).reshape(8, 8), columns=cols, index=idxs)
820-
821-
expected = df.loc[slice_]
822-
result = df.loc[non_reducing_slice(slice_)]
823-
tm.assert_frame_equal(result, expected)
824-
825771
def test_loc_slice_negative_stepsize(self):
826772
# GH#38071
827773
mi = MultiIndex.from_product([["a", "b"], [0, 1]])

pandas/tests/indexing/test_indexing.py

-51
Original file line numberDiff line numberDiff line change
@@ -23,10 +23,6 @@
2323
timedelta_range,
2424
)
2525
import pandas._testing as tm
26-
from pandas.core.indexing import (
27-
maybe_numeric_slice,
28-
non_reducing_slice,
29-
)
3026
from pandas.tests.indexing.common import _mklbl
3127
from pandas.tests.indexing.test_floats import gen_obj
3228

@@ -794,53 +790,6 @@ def test_range_in_series_indexing(self, size):
794790
s.loc[range(2)] = 43
795791
tm.assert_series_equal(s.loc[range(2)], Series(43.0, index=[0, 1]))
796792

797-
@pytest.mark.parametrize(
798-
"slc",
799-
[
800-
pd.IndexSlice[:, :],
801-
pd.IndexSlice[:, 1],
802-
pd.IndexSlice[1, :],
803-
pd.IndexSlice[[1], [1]],
804-
pd.IndexSlice[1, [1]],
805-
pd.IndexSlice[[1], 1],
806-
pd.IndexSlice[1],
807-
pd.IndexSlice[1, 1],
808-
slice(None, None, None),
809-
[0, 1],
810-
np.array([0, 1]),
811-
Series([0, 1]),
812-
],
813-
)
814-
def test_non_reducing_slice(self, slc):
815-
df = DataFrame([[0, 1], [2, 3]])
816-
817-
tslice_ = non_reducing_slice(slc)
818-
assert isinstance(df.loc[tslice_], DataFrame)
819-
820-
@pytest.mark.parametrize("box", [list, Series, np.array])
821-
def test_list_slice(self, box):
822-
# like dataframe getitem
823-
subset = box(["A"])
824-
825-
df = DataFrame({"A": [1, 2], "B": [3, 4]}, index=["A", "B"])
826-
expected = pd.IndexSlice[:, ["A"]]
827-
828-
result = non_reducing_slice(subset)
829-
tm.assert_frame_equal(df.loc[result], df.loc[expected])
830-
831-
def test_maybe_numeric_slice(self):
832-
df = DataFrame({"A": [1, 2], "B": ["c", "d"], "C": [True, False]})
833-
result = maybe_numeric_slice(df, slice_=None)
834-
expected = pd.IndexSlice[:, ["A"]]
835-
assert result == expected
836-
837-
result = maybe_numeric_slice(df, None, include_bool=True)
838-
expected = pd.IndexSlice[:, ["A", "C"]]
839-
assert all(result[1] == expected[1])
840-
result = maybe_numeric_slice(df, [1])
841-
expected = [1]
842-
assert result == expected
843-
844793
def test_partial_boolean_frame_indexing(self):
845794
# GH 17170
846795
df = DataFrame(

0 commit comments

Comments
 (0)