Skip to content

Commit 07d90cb

Browse files
committed
Added publish to dataframe repr
1 parent 5ea7731 commit 07d90cb

File tree

8 files changed

+95
-13
lines changed

8 files changed

+95
-13
lines changed

ci/requirements-2.7.pip

+2
Original file line numberDiff line numberDiff line change
@@ -4,3 +4,5 @@ pathlib
44
backports.lzma
55
py
66
PyCrypto
7+
mock
8+
ipython

ci/requirements-3.5.run

+1
Original file line numberDiff line numberDiff line change
@@ -18,3 +18,4 @@ pymysql
1818
psycopg2
1919
s3fs
2020
beautifulsoup4
21+
ipython

ci/requirements-3.6.run

+1
Original file line numberDiff line numberDiff line change
@@ -18,3 +18,4 @@ pymysql
1818
beautifulsoup4
1919
s3fs
2020
xarray
21+
ipython

doc/source/options.rst

+7-4
Original file line numberDiff line numberDiff line change
@@ -392,6 +392,9 @@ display.width 80 Width of the display in characters.
392392
IPython qtconsole, or IDLE do not run in a
393393
terminal and hence it is not possible
394394
to correctly detect the width.
395+
display.html.table_schema False Whether to publish a Table Schema
396+
representation for frontends that
397+
support it.
395398
html.border 1 A ``border=value`` attribute is
396399
inserted in the ``<table>`` tag
397400
for the DataFrame HTML repr.
@@ -516,11 +519,11 @@ Table Schema Display
516519
.. versionadded:: 0.20.0
517520

518521
``DataFrame`` and ``Series`` will publish a Table Schema representation
519-
by default. This can be disabled globally with the ``display.table_schema``
520-
option:
522+
by default. False by default, this can be enabled globally with the
523+
``display.html.table_schema`` option:
521524

522525
.. ipython:: python
523526
524-
pd.set_option('display.html.table_schema', False)
527+
pd.set_option('display.html.table_schema', True)
525528
526-
By default, only ``'display.max_rows'`` are serialized and published.
529+
Only ``'display.max_rows'`` are serialized and published.

doc/source/whatsnew/v0.20.0.txt

+13
Original file line numberDiff line numberDiff line change
@@ -174,7 +174,20 @@ the data.
174174
df
175175
df.to_json(orient='table')
176176

177+
178+
See :ref:`IO: Table Schema for more<io.table_schema>`.
179+
180+
Additionally, the repr for ``DataFrame`` and ``Series`` can now publish
181+
this JSON Table schema representation of the Series or DataFrame if you are
182+
using IPython (or another frontend like `nteract`_ using the Jupyter messaging
183+
protocol).
184+
This gives frontends like the Jupyter notebook and `nteract`_
185+
more flexiblity in how they display pandas objects, since they have
186+
more information about the data.
187+
You must enable this by setting the ``display.html.table_schema`` option to True.
188+
177189
.. _Table Schema: http://specs.frictionlessdata.io/json-table-schema/
190+
.. _nteract: http://nteract.io/
178191

179192
.. _whatsnew_0200.enhancements.other:
180193

pandas/core/config_init.py

+9
Original file line numberDiff line numberDiff line change
@@ -164,6 +164,13 @@
164164
(default: False)
165165
"""
166166

167+
pc_table_schema_doc = """
168+
: boolean
169+
Whether to publish a Table Schema representation for frontends
170+
that support it.
171+
(default: False)
172+
"""
173+
167174
pc_line_width_deprecation_warning = """\
168175
line_width has been deprecated, use display.width instead (currently both are
169176
identical)
@@ -339,6 +346,8 @@ def mpl_style_cb(key):
339346
validator=is_bool)
340347
cf.register_option('latex.longtable', False, pc_latex_longtable,
341348
validator=is_bool)
349+
cf.register_option('html.table_schema', False, pc_table_schema_doc,
350+
validator=is_bool)
342351

343352
cf.deprecate_option('display.line_width',
344353
msg=pc_line_width_deprecation_warning,

pandas/core/generic.py

+43-9
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
import operator
55
import weakref
66
import gc
7+
import json
78

89
import numpy as np
910
import pandas.lib as lib
@@ -129,6 +130,37 @@ def __init__(self, data, axes=None, copy=False, dtype=None,
129130
object.__setattr__(self, '_data', data)
130131
object.__setattr__(self, '_item_cache', {})
131132

133+
def _ipython_display_(self):
134+
try:
135+
from IPython.display import display
136+
except ImportError:
137+
return None
138+
139+
# Series doesn't define _repr_html_ or _repr_latex_
140+
latex = self._repr_latex_() if hasattr(self, '_repr_latex_') else None
141+
html = self._repr_html_() if hasattr(self, '_repr_html_') else None
142+
table_schema = self._repr_table_schema_()
143+
# We need the inital newline since we aren't going through the
144+
# usual __repr__. See
145+
# https://github.com/pandas-dev/pandas/pull/14904#issuecomment-277829277
146+
text = "\n" + repr(self)
147+
148+
reprs = {"text/plain": text, "text/html": html, "text/latex": latex,
149+
"application/vnd.dataresource+json": table_schema}
150+
reprs = {k: v for k, v in reprs.items() if v}
151+
display(reprs, raw=True)
152+
153+
def _repr_table_schema_(self):
154+
"""
155+
Not a real Jupyter special repr method, but we use the same
156+
naming convention.
157+
"""
158+
if config.get_option("display.html.table_schema"):
159+
data = self.head(config.get_option('display.max_rows'))
160+
payload = json.loads(data.to_json(orient='table'),
161+
object_pairs_hook=collections.OrderedDict)
162+
return payload
163+
132164
def _validate_dtype(self, dtype):
133165
""" validate the passed dtype """
134166

@@ -1094,10 +1126,9 @@ def __setstate__(self, state):
10941126
strings before writing.
10951127
"""
10961128

1097-
def to_json(self, path_or_buf=None, orient=None, date_format='epoch',
1098-
timedelta_format='epoch', double_precision=10,
1099-
force_ascii=True, date_unit='ms', default_handler=None,
1100-
lines=False):
1129+
def to_json(self, path_or_buf=None, orient=None, date_format=None,
1130+
double_precision=10, force_ascii=True, date_unit='ms',
1131+
default_handler=None, lines=False):
11011132
"""
11021133
Convert the object to a JSON string.
11031134
@@ -1131,17 +1162,16 @@ def to_json(self, path_or_buf=None, orient=None, date_format='epoch',
11311162
- columns : dict like {column -> {index -> value}}
11321163
- values : just the values array
11331164
- table : dict like {'schema': {schema}, 'data': {data}}
1134-
the schema component is a `Table Schema_`
11351165
describing the data, and the data component is
11361166
like ``orient='records'``.
11371167
11381168
.. versionchanged:: 0.20.0
11391169
1140-
date_format : {'epoch', 'iso'}
1170+
date_format : {None, 'epoch', 'iso'}
11411171
Type of date conversion. `epoch` = epoch milliseconds,
1142-
`iso` = ISO8601. Default is epoch, except when orient is
1143-
table_schema, in which case this parameter is ignored
1144-
and iso formatting is always used.
1172+
`iso` = ISO8601. The default depends on the `orient`. For
1173+
`orient='table'`, the default is `'iso'`. For all other orients,
1174+
the default is `'epoch'`.
11451175
double_precision : The number of decimal places to use when encoding
11461176
floating point values, default 10.
11471177
force_ascii : force encoded string to be ASCII, default True.
@@ -1203,6 +1233,10 @@ def to_json(self, path_or_buf=None, orient=None, date_format='epoch',
12031233
"""
12041234

12051235
from pandas.io import json
1236+
if date_format is None and orient == 'table':
1237+
date_format = 'iso'
1238+
elif date_format is None:
1239+
date_format = 'epoch'
12061240
return json.to_json(path_or_buf=path_or_buf, obj=self, orient=orient,
12071241
date_format=date_format,
12081242
double_precision=double_precision,

pandas/util/testing.py

+19
Original file line numberDiff line numberDiff line change
@@ -424,6 +424,25 @@ def _skip_if_not_us_locale():
424424
import pytest
425425
pytest.skip("Specific locale is set {0}".format(lang))
426426

427+
428+
def _skip_if_no_mock():
429+
try:
430+
import mock # noqa
431+
except ImportError:
432+
try:
433+
from unittest import mock # noqa
434+
except ImportError:
435+
import nose
436+
raise nose.SkipTest("mock is not installed")
437+
438+
439+
def _skip_if_no_ipython():
440+
try:
441+
import IPython # noqa
442+
except ImportError:
443+
import nose
444+
raise nose.SkipTest("IPython not installed")
445+
427446
# -----------------------------------------------------------------------------
428447
# locale utilities
429448

0 commit comments

Comments
 (0)