Skip to content

Commit 8282511

Browse files
author
Marco Gorelli
committed
✨ Add to_markdown method
1 parent 95e1a63 commit 8282511

File tree

6 files changed

+46
-0
lines changed

6 files changed

+46
-0
lines changed

doc/source/whatsnew/v1.0.0.rst

+1
Original file line numberDiff line numberDiff line change
@@ -207,6 +207,7 @@ Other enhancements
207207
- The ``partition_cols`` argument in :meth:`DataFrame.to_parquet` now accepts a string (:issue:`27117`)
208208
- :func:`to_parquet` now appropriately handles the ``schema`` argument for user defined schemas in the pyarrow engine. (:issue: `30270`)
209209
- DataFrame constructor preserve `ExtensionArray` dtype with `ExtensionArray` (:issue:`11363`)
210+
- :meth:`DataFrame.to_markdown` added (:issue:`11052`)
210211

211212

212213
Build Changes

environment.yml

+1
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@ dependencies:
7272
- matplotlib>=2.2.2 # pandas.plotting, Series.plot, DataFrame.plot
7373
- numexpr>=2.6.8
7474
- scipy>=1.1
75+
- tabulate
7576

7677
# optional for io
7778
- beautifulsoup4>=4.6.0 # pandas.read_html

pandas/core/frame.py

+24
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@
3636
from pandas._config import get_option
3737

3838
from pandas._libs import algos as libalgos, lib
39+
from pandas.compat._optional import import_optional_dependency
3940
from pandas.compat.numpy import function as nv
4041
from pandas.util._decorators import (
4142
Appender,
@@ -1964,6 +1965,29 @@ def to_feather(self, path):
19641965

19651966
to_feather(self, path)
19661967

1968+
def to_markdown(self):
1969+
"""
1970+
Print a DataFrame in markdown-friendly format.
1971+
1972+
.. versionadded:: 1.0
1973+
1974+
Returns
1975+
-------
1976+
str
1977+
DataFrame in markdown-friendly format.
1978+
1979+
Examples
1980+
--------
1981+
>>> df = pd.DataFrame(data={'col1': [1, 2], 'col2': [3, 4]})
1982+
>>> print(df.to_markdown())
1983+
| | col1 | col2 |
1984+
|---:|-------:|-------:|
1985+
| 0 | 1 | 3 |
1986+
| 1 | 2 | 4 |
1987+
"""
1988+
tabulate = import_optional_dependency("tabulate")
1989+
return self.pipe(tabulate.tabulate, headers="keys", tablefmt="pipe")
1990+
19671991
@deprecate_kwarg(old_arg_name="fname", new_arg_name="path")
19681992
def to_parquet(
19691993
self,
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
import pandas.util._test_decorators as td
2+
3+
import pandas as pd
4+
5+
6+
@td.skip_if_no_tabulate
7+
def test_to_markdown():
8+
df = pd.DataFrame([1, 2, 3])
9+
result = df.to_markdown()
10+
assert (
11+
result == "| | 0 |\n|---:|----:|\n| 0 | 1 |\n| 1 | 2 |\n| 2 | 3 |"
12+
)

pandas/util/_test_decorators.py

+7
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,10 @@ def _skip_if_no_scipy():
119119
)
120120

121121

122+
def _skip_if_no_tabulate():
123+
return not safe_import("tabulate")
124+
125+
122126
def skip_if_installed(package: str) -> Callable:
123127
"""
124128
Skip a test if a package is installed.
@@ -193,6 +197,9 @@ def skip_if_no(package: str, min_version: Optional[str] = None) -> Callable:
193197
not _USE_NUMEXPR,
194198
reason=f"numexpr enabled->{_USE_NUMEXPR}, " f"installed->{_NUMEXPR_INSTALLED}",
195199
)
200+
skip_if_no_tabulate = pytest.mark.skipif(
201+
_skip_if_no_tabulate(), reason="Missing tabulate requirement"
202+
)
196203

197204

198205
def skip_if_np_lt(ver_str, reason=None, *args, **kwds):

requirements-dev.txt

+1
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ jinja2
4747
matplotlib>=2.2.2
4848
numexpr>=2.6.8
4949
scipy>=1.1
50+
tabulate
5051
beautifulsoup4>=4.6.0
5152
fastparquet>=0.3.2
5253
html5lib

0 commit comments

Comments
 (0)