Skip to content

Commit 7ab73a9

Browse files
MarcoGorellijreback
authored andcommitted
[ENH] Add to_markdown method (#30350)
1 parent fb20b26 commit 7ab73a9

File tree

13 files changed

+147
-2
lines changed

13 files changed

+147
-2
lines changed

ci/deps/travis-37.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ dependencies:
2020
- pyarrow
2121
- pytz
2222
- s3fs
23+
- tabulate
2324
- pyreadstat
2425
- pip
2526
- pip:

ci/deps/travis-38.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,3 +17,4 @@ dependencies:
1717
- nomkl
1818
- pytz
1919
- pip
20+
- tabulate==0.8.3

doc/source/getting_started/install.rst

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -234,7 +234,8 @@ Optional dependencies
234234
~~~~~~~~~~~~~~~~~~~~~
235235

236236
Pandas has many optional dependencies that are only used for specific methods.
237-
For example, :func:`pandas.read_hdf` requires the ``pytables`` package. If the
237+
For example, :func:`pandas.read_hdf` requires the ``pytables`` package, while
238+
:meth:`DataFrame.to_markdown` requires the ``tabulate`` package. If the
238239
optional dependency is not installed, pandas will raise an ``ImportError`` when
239240
the method requiring that dependency is called.
240241

@@ -264,6 +265,7 @@ pyreadstat SPSS files (.sav) reading
264265
pytables 3.4.2 HDF5 reading / writing
265266
qtpy Clipboard I/O
266267
s3fs 0.3.0 Amazon S3 access
268+
tabulate 0.8.3 Printing in Markdown-friendly format (see `tabulate`_)
267269
xarray 0.8.2 pandas-like API for N-dimensional data
268270
xclip Clipboard I/O on linux
269271
xlrd 1.1.0 Excel reading
@@ -301,3 +303,4 @@ top-level :func:`~pandas.read_html` function:
301303
.. _html5lib: https://github.com/html5lib/html5lib-python
302304
.. _BeautifulSoup4: http://www.crummy.com/software/BeautifulSoup
303305
.. _lxml: http://lxml.de
306+
.. _tabulate: https://github.com/astanin/python-tabulate

doc/source/reference/frame.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -361,4 +361,5 @@ Serialization / IO / conversion
361361
DataFrame.to_records
362362
DataFrame.to_string
363363
DataFrame.to_clipboard
364+
DataFrame.to_markdown
364365
DataFrame.style

doc/source/reference/series.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -578,3 +578,4 @@ Serialization / IO / conversion
578578
Series.to_string
579579
Series.to_clipboard
580580
Series.to_latex
581+
Series.to_markdown

doc/source/whatsnew/v1.0.0.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -209,6 +209,7 @@ Other enhancements
209209
- :func:`to_parquet` now appropriately handles the ``schema`` argument for user defined schemas in the pyarrow engine. (:issue: `30270`)
210210
- DataFrame constructor preserve `ExtensionArray` dtype with `ExtensionArray` (:issue:`11363`)
211211
- :meth:`DataFrame.sort_values` and :meth:`Series.sort_values` have gained ``ignore_index`` keyword to be able to reset index after sorting (:issue:`30114`)
212+
- :meth:`DataFrame.to_markdown` and :meth:`Series.to_markdown` added (:issue:`11052`)
212213

213214
- :meth:`DataFrame.drop_duplicates` has gained ``ignore_index`` keyword to reset index (:issue:`30114`)
214215

environment.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,5 +100,6 @@ dependencies:
100100
- sqlalchemy # pandas.read_sql, DataFrame.to_sql
101101
- xarray # DataFrame.to_xarray
102102
- pyreadstat # pandas.read_spss
103+
- tabulate>=0.8.3 # DataFrame.to_markdown
103104
- pip:
104105
- git+https://github.com/pandas-dev/pandas-sphinx-theme.git@master

pandas/compat/_optional.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
"scipy": "0.19.0",
2424
"sqlalchemy": "1.1.4",
2525
"tables": "3.4.2",
26+
"tabulate": "0.8.3",
2627
"xarray": "0.8.2",
2728
"xlrd": "1.1.0",
2829
"xlwt": "1.2.0",

pandas/core/frame.py

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
import sys
1616
from textwrap import dedent
1717
from typing import (
18+
IO,
1819
Any,
1920
FrozenSet,
2021
Hashable,
@@ -37,6 +38,7 @@
3738

3839
from pandas._libs import algos as libalgos, lib
3940
from pandas._typing import Axes, Dtype, FilePathOrBuffer
41+
from pandas.compat._optional import import_optional_dependency
4042
from pandas.compat.numpy import function as nv
4143
from pandas.util._decorators import (
4244
Appender,
@@ -118,6 +120,7 @@
118120
from pandas.core.ops.missing import dispatch_fill_zeros
119121
from pandas.core.series import Series
120122

123+
from pandas.io.common import get_filepath_or_buffer
121124
from pandas.io.formats import console, format as fmt
122125
from pandas.io.formats.printing import pprint_thing
123126
import pandas.plotting
@@ -1964,6 +1967,36 @@ def to_feather(self, path):
19641967

19651968
to_feather(self, path)
19661969

1970+
@Appender(
1971+
"""
1972+
Examples
1973+
--------
1974+
>>> df = pd.DataFrame(
1975+
... data={"animal_1": ["elk", "pig"], "animal_2": ["dog", "quetzal"]}
1976+
... )
1977+
>>> print(df.to_markdown())
1978+
| | animal_1 | animal_2 |
1979+
|---:|:-----------|:-----------|
1980+
| 0 | elk | dog |
1981+
| 1 | pig | quetzal |
1982+
"""
1983+
)
1984+
@Substitution(klass="DataFrame")
1985+
@Appender(_shared_docs["to_markdown"])
1986+
def to_markdown(
1987+
self, buf: Optional[IO[str]] = None, mode: Optional[str] = None, **kwargs,
1988+
) -> Optional[str]:
1989+
kwargs.setdefault("headers", "keys")
1990+
kwargs.setdefault("tablefmt", "pipe")
1991+
tabulate = import_optional_dependency("tabulate")
1992+
result = tabulate.tabulate(self, **kwargs)
1993+
if buf is None:
1994+
return result
1995+
buf, _, _, _ = get_filepath_or_buffer(buf, mode=mode)
1996+
assert buf is not None # Help mypy.
1997+
buf.writelines(result)
1998+
return None
1999+
19672000
@deprecate_kwarg(old_arg_name="fname", new_arg_name="path")
19682001
def to_parquet(
19692002
self,

pandas/core/generic.py

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1970,6 +1970,30 @@ def _repr_data_resource_(self):
19701970
# ----------------------------------------------------------------------
19711971
# I/O Methods
19721972

1973+
_shared_docs[
1974+
"to_markdown"
1975+
] = """
1976+
Print %(klass)s in Markdown-friendly format.
1977+
1978+
.. versionadded:: 1.0.0
1979+
1980+
Parameters
1981+
----------
1982+
buf : writable buffer, defaults to sys.stdout
1983+
Where to send the output. By default, the output is printed to
1984+
sys.stdout. Pass a writable buffer if you need to further process
1985+
the output.
1986+
mode : str, optional
1987+
Mode in which file is opened.
1988+
**kwargs
1989+
These parameters will be passed to `tabulate`.
1990+
1991+
Returns
1992+
-------
1993+
str
1994+
%(klass)s in Markdown-friendly format.
1995+
"""
1996+
19731997
_shared_docs[
19741998
"to_excel"
19751999
] = """

0 commit comments

Comments
 (0)