Skip to content

Commit 8ff7998

Browse files
Index repr: allow unequal number of elements on one line
Inspired by numpy's array2string
1 parent a80ae5e commit 8ff7998

File tree

1 file changed

+56
-58
lines changed

1 file changed

+56
-58
lines changed

pandas/core/index.py

+56-58
Original file line numberDiff line numberDiff line change
@@ -434,6 +434,11 @@ def _format_data(self):
434434
"""
435435
Return the formatted data as a unicode string
436436
"""
437+
from pandas.core.format import get_console_size
438+
display_width, _ = get_console_size()
439+
if display_width is None:
440+
display_width = get_option('display.width')
441+
437442
space1 = "\n%s" % (' ' * (len(self.__class__.__name__) + 1))
438443
space2 = "\n%s" % (' ' * (len(self.__class__.__name__) + 2))
439444

@@ -442,42 +447,18 @@ def _format_data(self):
442447
formatter = self._formatter_func
443448
needs_justify = self.inferred_type in ['string','categorical']
444449

445-
def best_len(values):
446-
return max([len(x) for x in values]) + 2
447-
448-
def best_rows(values, max_len):
449-
from pandas.core.format import get_console_size
450-
display_width, _ = get_console_size()
451-
if display_width is None:
452-
display_width = get_option('display.width')
453-
n_per_row = (display_width - len(self.__class__.__name__) - 2) // max_len
454-
n_rows = int(ceil(len(values) / float(n_per_row)))
455-
return n_per_row, n_rows
456-
457-
def best_fit(values, max_len, n_rows=None, justify=False):
458-
459-
# number of rows to generate
460-
if n_rows is None:
461-
n_per_row, n_rows = best_rows(values, max_len)
462-
else:
463-
n_per_row = len(values)
450+
def _extend_line(s, line, value, display_width, next_line_prefix):
451+
if len(line.rstrip()) + len(value.rstrip()) >= display_width:
452+
s += line.rstrip()
453+
line = next_line_prefix
454+
line += value
455+
return s, line
464456

465-
# adjust all values to max length if we have multi-lines
466-
if justify:
467-
values = [values[0].rjust(max_len-2)] + [x.rjust(max_len-1) for x in values[1:]]
468-
multi_line_space = space1
457+
def best_len(values):
458+
if values:
459+
return max([len(x) for x in values])
469460
else:
470-
multi_line_space = space2
471-
472-
sep_elements = sep + ' '
473-
summary = ''
474-
for i in range(n_rows - 1):
475-
summary += sep_elements.join(values[i*n_per_row:(i+1)*n_per_row])
476-
summary += sep
477-
summary += multi_line_space
478-
summary += sep_elements.join(values[(n_rows - 1)*n_per_row:n_rows*n_per_row])
479-
480-
return summary
461+
return 0
481462

482463
n = len(self)
483464
if n == 0:
@@ -489,41 +470,58 @@ def best_fit(values, max_len, n_rows=None, justify=False):
489470
first = formatter(self[0])
490471
last = formatter(self[-1])
491472
summary = '[%s, %s], ' % (first, last)
492-
elif n > max_seq_items:
493-
n = min(max_seq_items//2,10)
494-
495-
head = [ formatter(x) for x in self[:n] ]
496-
tail = [ formatter(x) for x in self[-n:] ]
497-
max_len = max(best_len(head),best_len(tail))
473+
else:
474+
if n > max_seq_items:
475+
n = min(max_seq_items//2,10)
476+
head = [ formatter(x) for x in self[:n] ]
477+
tail = [ formatter(x) for x in self[-n:] ]
478+
summary_insert = True
479+
else:
480+
head = []
481+
tail = [ formatter(x) for x in self ]
482+
summary_insert = False
498483

499484
if needs_justify:
500-
n_rows = 1
501485
justify = False
502486
else:
503-
n_rows = None
504487
justify = True
505488

506-
summary = '['
507-
summary += best_fit(head, max_len, n_rows=n_rows, justify=justify)
508-
summary += ',' + space1 + ' ...' + space2
509-
summary += best_fit(tail, max_len, n_rows=n_rows, justify=justify)
489+
# adjust all values to max length if needed
490+
if justify:
491+
max_len = max(best_len(head), best_len(tail))
492+
head = [x.rjust(max_len) for x in head]
493+
tail = [x.rjust(max_len) for x in tail]
494+
495+
summary = ""
496+
line = space2
497+
498+
for i in range(len(head)):
499+
word = head[i] + sep + ' '
500+
summary, line = _extend_line(summary, line, word,
501+
display_width, space2)
502+
if summary_insert:
503+
summary += line + space2 + '...'
504+
line = space2
505+
506+
for i in range(len(tail)-1):
507+
word = tail[i] + sep + ' '
508+
summary, line = _extend_line(summary, line, word,
509+
display_width, space2)
510+
511+
# last value: no sep added + 1 space of width used for trailing ','
512+
summary, line = _extend_line(summary, line, tail[-1],
513+
display_width - 2, space2)
514+
summary += line
510515
summary += '],'
511-
summary += space1
512-
513-
else:
514-
values = [ formatter(x) for x in self ]
515516

516-
max_len = best_len(values)
517-
n_per_row, n_rows = best_rows(values, max_len)
518-
519-
summary = '['
520-
summary += best_fit(values, max_len)
521-
summary += '],'
522-
if n_rows > 1:
517+
if len(summary) > (display_width):
523518
summary += space1
524-
else:
519+
else: # one row
525520
summary += ' '
526521

522+
# remove initial space
523+
summary = '[' + summary[len(space2):]
524+
527525
return summary
528526

529527
def _format_attrs(self):

0 commit comments

Comments
 (0)