Skip to content

Commit 6d4819b

Browse files
authored
REF: simplify Categorical.__repr__ (#55391)
* REF: remove unused arguments from private Categorical methods * REF: remove unused args from CategoricalFormatter * REF: remove CategoricalFormatter
1 parent 4145278 commit 6d4819b

File tree

2 files changed

+35
-101
lines changed

2 files changed

+35
-101
lines changed

pandas/core/arrays/categorical.py

+34-33
Original file line numberDiff line numberDiff line change
@@ -2151,21 +2151,6 @@ def _formatter(self, boxed: bool = False):
21512151
# Defer to CategoricalFormatter's formatter.
21522152
return None
21532153

2154-
def _tidy_repr(self, max_vals: int = 10, footer: bool = True) -> str:
2155-
"""
2156-
a short repr displaying only max_vals and an optional (but default
2157-
footer)
2158-
"""
2159-
num = max_vals // 2
2160-
head = self[:num]._get_repr(length=False, footer=False)
2161-
tail = self[-(max_vals - num) :]._get_repr(length=False, footer=False)
2162-
2163-
result = f"{head[:-1]}, ..., {tail[1:]}"
2164-
if footer:
2165-
result = f"{result}\n{self._repr_footer()}"
2166-
2167-
return str(result)
2168-
21692154
def _repr_categories(self) -> list[str]:
21702155
"""
21712156
return the base repr for the categories
@@ -2221,33 +2206,49 @@ def _repr_categories_info(self) -> str:
22212206
# replace to simple save space by
22222207
return f"{levheader}[{levstring.replace(' < ... < ', ' ... ')}]"
22232208

2224-
def _repr_footer(self) -> str:
2225-
info = self._repr_categories_info()
2226-
return f"Length: {len(self)}\n{info}"
2227-
2228-
def _get_repr(
2229-
self, length: bool = True, na_rep: str = "NaN", footer: bool = True
2230-
) -> str:
2209+
def _get_values_repr(self) -> str:
22312210
from pandas.io.formats import format as fmt
22322211

2233-
formatter = fmt.CategoricalFormatter(
2234-
self, length=length, na_rep=na_rep, footer=footer
2212+
assert len(self) > 0
2213+
2214+
vals = self._internal_get_values()
2215+
fmt_values = fmt.format_array(
2216+
vals,
2217+
None,
2218+
float_format=None,
2219+
na_rep="NaN",
2220+
quoting=QUOTE_NONNUMERIC,
22352221
)
2236-
result = formatter.to_string()
2237-
return str(result)
2222+
2223+
fmt_values = [i.strip() for i in fmt_values]
2224+
joined = ", ".join(fmt_values)
2225+
result = "[" + joined + "]"
2226+
return result
22382227

22392228
def __repr__(self) -> str:
22402229
"""
22412230
String representation.
22422231
"""
2243-
_maxlen = 10
2244-
if len(self._codes) > _maxlen:
2245-
result = self._tidy_repr(_maxlen)
2246-
elif len(self._codes) > 0:
2247-
result = self._get_repr(length=len(self) > _maxlen)
2232+
footer = self._repr_categories_info()
2233+
length = len(self)
2234+
max_len = 10
2235+
if length > max_len:
2236+
# In long cases we do not display all entries, so we add Length
2237+
# information to the __repr__.
2238+
num = max_len // 2
2239+
head = self[:num]._get_values_repr()
2240+
tail = self[-(max_len - num) :]._get_values_repr()
2241+
body = f"{head[:-1]}, ..., {tail[1:]}"
2242+
length_info = f"Length: {len(self)}"
2243+
result = f"{body}\n{length_info}\n{footer}"
2244+
elif length > 0:
2245+
body = self._get_values_repr()
2246+
result = f"{body}\n{footer}"
22482247
else:
2249-
msg = self._get_repr(length=False, footer=True).replace("\n", ", ")
2250-
result = f"[], {msg}"
2248+
# In the empty case we use a comma instead of newline to get
2249+
# a more compact __repr__
2250+
body = "[]"
2251+
result = f"{body}, {footer}"
22512252

22522253
return result
22532254

pandas/io/formats/format.py

+1-68
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,7 @@
1212
Sequence,
1313
)
1414
from contextlib import contextmanager
15-
from csv import (
16-
QUOTE_NONE,
17-
QUOTE_NONNUMERIC,
18-
)
15+
from csv import QUOTE_NONE
1916
from decimal import Decimal
2017
from functools import partial
2118
from io import StringIO
@@ -200,70 +197,6 @@
200197
"""
201198

202199

203-
class CategoricalFormatter:
204-
def __init__(
205-
self,
206-
categorical: Categorical,
207-
buf: IO[str] | None = None,
208-
length: bool = True,
209-
na_rep: str = "NaN",
210-
footer: bool = True,
211-
) -> None:
212-
self.categorical = categorical
213-
self.buf = buf if buf is not None else StringIO("")
214-
self.na_rep = na_rep
215-
self.length = length
216-
self.footer = footer
217-
self.quoting = QUOTE_NONNUMERIC
218-
219-
def _get_footer(self) -> str:
220-
footer = ""
221-
222-
if self.length:
223-
if footer:
224-
footer += ", "
225-
footer += f"Length: {len(self.categorical)}"
226-
227-
level_info = self.categorical._repr_categories_info()
228-
229-
# Levels are added in a newline
230-
if footer:
231-
footer += "\n"
232-
footer += level_info
233-
234-
return str(footer)
235-
236-
def _get_formatted_values(self) -> list[str]:
237-
return format_array(
238-
self.categorical._internal_get_values(),
239-
None,
240-
float_format=None,
241-
na_rep=self.na_rep,
242-
quoting=self.quoting,
243-
)
244-
245-
def to_string(self) -> str:
246-
categorical = self.categorical
247-
248-
if len(categorical) == 0:
249-
if self.footer:
250-
return self._get_footer()
251-
else:
252-
return ""
253-
254-
fmt_values = self._get_formatted_values()
255-
256-
fmt_values = [i.strip() for i in fmt_values]
257-
values = ", ".join(fmt_values)
258-
result = ["[" + values + "]"]
259-
if self.footer:
260-
footer = self._get_footer()
261-
if footer:
262-
result.append(footer)
263-
264-
return str("\n".join(result))
265-
266-
267200
class SeriesFormatter:
268201
def __init__(
269202
self,

0 commit comments

Comments
 (0)