Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

BUG: fix max_columns=0, close #2856 #2881

Merged
merged 5 commits into from
Apr 12, 2013
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions pandas/core/config_init.py
Original file line number Diff line number Diff line change
Expand Up @@ -212,6 +212,9 @@ def mpl_style_cb(key):
cf.register_option('mpl_style', None, pc_mpl_style_doc,
validator=is_one_of_factory([None, False, 'default']),
cb=mpl_style_cb)
cf.register_option('height', 100, 'TODO', validator=is_int)
cf.register_option('width',80, 'TODO', validator=is_int)
cf.deprecate_option('display.line_width', msg='TODO', rkey='display.width')

tc_sim_interactive_doc = """
: boolean
Expand Down
104 changes: 54 additions & 50 deletions pandas/core/frame.py
Original file line number Diff line number Diff line change
Expand Up @@ -599,44 +599,39 @@ def empty(self):
def __nonzero__(self):
raise ValueError("Cannot call bool() on DataFrame.")

def _need_info_repr_(self):
def _repr_fits_boundaries_(self):
"""
Check if it is needed to use info/summary view to represent a
particular DataFrame.
Check if repr fits in boundaries imposed by the following sets of
display options:
* width, height
* max_rows, max_columns
In case off non-interactive session, no boundaries apply.
"""
if not com.in_interactive_session():
return True

if com.in_qtconsole():
terminal_width, terminal_height = 100, 100
else:
terminal_width, terminal_height = get_terminal_size()
max_rows = (terminal_height if get_option("display.max_rows") == 0
else get_option("display.max_rows"))
max_columns = get_option("display.max_columns")
expand_repr = get_option("display.expand_frame_repr")
terminal_width, terminal_height = get_terminal_size()

if max_columns > 0:
if (len(self.index) <= max_rows and
(len(self.columns) <= max_columns and expand_repr)):
return False
else:
return True
else:
# save us
if (len(self.index) > max_rows or
(com.in_interactive_session() and
len(self.columns) > terminal_width // 2 and
not expand_repr)):
return True
else:
buf = StringIO()
self.to_string(buf=buf)
value = buf.getvalue()
if (max([len(l) for l in value.split('\n')]) > terminal_width
and com.in_interactive_session()
and not expand_repr):
return True
else:
return False
# check vertical boundaries (excluding column axis area)
max_rows = get_option("display.max_rows") or terminal_height
display_height = get_option("display.height") or terminal_height
if len(self.index) > min(max_rows, display_height):
return False

# check horizontal boundaries (including index axis area)
max_columns = get_option("display.max_columns")
display_width = get_option("display.width") or terminal_width
nb_columns = len(self.columns)
if max_columns and nb_columns > max_columns:
return False
if nb_columns > (display_width // 2):
return False

buf = StringIO()
self.to_string(buf=buf)
value = buf.getvalue()
repr_width = max([len(l) for l in value.split('\n')])
return repr_width <= display_width

def __str__(self):
"""
Expand Down Expand Up @@ -668,26 +663,29 @@ def __unicode__(self):
py2/py3.
"""
buf = StringIO(u"")
if self._need_info_repr_():
max_info_rows = get_option('display.max_info_rows')
verbose = max_info_rows is None or self.shape[0] <= max_info_rows
self.info(buf=buf, verbose=verbose)
if self._repr_fits_boundaries_():
self.to_string(buf=buf)
else:
is_wide = self._need_wide_repr()
line_width = None
if is_wide:
line_width = get_option('display.line_width')
self.to_string(buf=buf, line_width=line_width)
terminal_width, terminal_height = get_terminal_size()
max_rows = get_option("display.max_rows") or terminal_height
# Expand or info? Decide based on option display.expand_frame_repr
# and keep it sane for the number of display rows used by the
# expanded repr.
if (get_option("display.expand_frame_repr") and
len(self.columns) < max_rows):
line_width = get_option("display.width") or terminal_width
self.to_string(buf=buf, line_width=line_width)
else:
max_info_rows = get_option('display.max_info_rows')
verbose = (max_info_rows is None or
self.shape[0] <= max_info_rows)
self.info(buf=buf, verbose=verbose)

value = buf.getvalue()
assert type(value) == unicode

return value

def _need_wide_repr(self):
return (get_option("display.expand_frame_repr")
and com.in_interactive_session())

def __repr__(self):
"""
Return a string representation for a particular DataFrame
Expand All @@ -705,12 +703,18 @@ def _repr_html_(self):
raise ValueError('Disable HTML output in QtConsole')

if get_option("display.notebook_repr_html"):
if self._need_info_repr_():
return None
else:
if self._repr_fits_boundaries_():
return ('<div style="max-height:1000px;'
'max-width:1500px;overflow:auto;">\n' +
self.to_html() + '\n</div>')
else:
buf = StringIO(u"")
max_info_rows = get_option('display.max_info_rows')
verbose = (max_info_rows is None or
self.shape[0] <= max_info_rows)
self.info(buf=buf, verbose=verbose)
info = buf.getvalue().replace('<', '&lt').replace('>', '&gt')
return ('<pre>\n' + info + '\n</pre>')
else:
return None

Expand Down
67 changes: 65 additions & 2 deletions pandas/tests/test_format.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
from pandas.util.py3compat import lzip
import pandas.core.format as fmt
import pandas.util.testing as tm
from pandas.util.terminal import get_terminal_size
import pandas
import pandas as pd
from pandas.core.config import (set_option, get_option,
Expand All @@ -31,6 +32,17 @@ def curpath():
pth, _ = os.path.split(os.path.abspath(__file__))
return pth

def has_info_repr(df):
r = repr(df)
return r.split('\n')[0].startswith("<class")

def has_expanded_repr(df):
r = repr(df)
for line in r.split('\n'):
if line.endswith('\\'):
return True
return False


class TestDataFrameFormatting(unittest.TestCase):
_multiprocess_can_split_ = True
Expand Down Expand Up @@ -144,6 +156,57 @@ def test_repr_no_backslash(self):
df = DataFrame(np.random.randn(10, 4))
self.assertTrue('\\' not in repr(df))

def test_expand_frame_repr(self):
df_small = DataFrame('hello', [0], [0])
df_wide = DataFrame('hello', [0], range(10))

with option_context('mode.sim_interactive', True):
with option_context('display.width', 50):
with option_context('display.expand_frame_repr', True):
self.assertFalse(has_info_repr(df_small))
self.assertFalse(has_expanded_repr(df_small))
self.assertFalse(has_info_repr(df_wide))
self.assertTrue(has_expanded_repr(df_wide))

with option_context('display.expand_frame_repr', False):
self.assertFalse(has_info_repr(df_small))
self.assertFalse(has_expanded_repr(df_small))
self.assertTrue(has_info_repr(df_wide))
self.assertFalse(has_expanded_repr(df_wide))

def test_repr_max_columns_max_rows(self):
term_width, term_height = get_terminal_size()
if term_width < 10 or term_height < 10:
raise nose.SkipTest

def mkframe(n):
index = ['%05d' % i for i in range(n)]
return DataFrame(0, index, index)

with option_context('mode.sim_interactive', True):
with option_context('display.width', term_width * 2):
with option_context('display.max_rows', 5,
'display.max_columns', 5):
self.assertFalse(has_expanded_repr(mkframe(4)))
self.assertFalse(has_expanded_repr(mkframe(5)))
self.assertFalse(has_expanded_repr(mkframe(6)))
self.assertTrue(has_info_repr(mkframe(6)))

with option_context('display.max_rows', 20,
'display.max_columns', 5):
# Out off max_columns boundary, but no extending
# occurs ... can improve?
self.assertFalse(has_expanded_repr(mkframe(6)))
self.assertFalse(has_info_repr(mkframe(6)))

with option_context('display.max_columns', 0,
'display.max_rows', term_width * 20,
'display.width', 0):
df = mkframe((term_width // 7) - 2)
self.assertFalse(has_expanded_repr(df))
df = mkframe((term_width // 7) + 2)
self.assertTrue(has_expanded_repr(df))

def test_to_string_repr_unicode(self):
buf = StringIO()

Expand Down Expand Up @@ -1176,8 +1239,8 @@ def get_ipython():
self.assert_(repstr is not None)

fmt.set_printoptions(max_rows=5, max_columns=2)

self.assert_(self.frame._repr_html_() is None)
repstr = self.frame._repr_html_()
self.assert_('class' in repstr) # info fallback

fmt.reset_printoptions()

Expand Down