diff --git a/pandas/tests/formats/test_eng_formatting.py b/pandas/tests/formats/test_eng_formatting.py
new file mode 100644
index 0000000000000..d2badd4fc160a
--- /dev/null
+++ b/pandas/tests/formats/test_eng_formatting.py
@@ -0,0 +1,195 @@
+import numpy as np
+import pandas as pd
+from pandas import DataFrame
+from pandas.compat import u
+import pandas.formats.format as fmt
+from pandas.util import testing as tm
+
+
+class TestEngFormatter(tm.TestCase):
+
+ def test_eng_float_formatter(self):
+ df = DataFrame({'A': [1.41, 141., 14100, 1410000.]})
+
+ fmt.set_eng_float_format()
+ result = df.to_string()
+ expected = (' A\n'
+ '0 1.410E+00\n'
+ '1 141.000E+00\n'
+ '2 14.100E+03\n'
+ '3 1.410E+06')
+ self.assertEqual(result, expected)
+
+ fmt.set_eng_float_format(use_eng_prefix=True)
+ result = df.to_string()
+ expected = (' A\n'
+ '0 1.410\n'
+ '1 141.000\n'
+ '2 14.100k\n'
+ '3 1.410M')
+ self.assertEqual(result, expected)
+
+ fmt.set_eng_float_format(accuracy=0)
+ result = df.to_string()
+ expected = (' A\n'
+ '0 1E+00\n'
+ '1 141E+00\n'
+ '2 14E+03\n'
+ '3 1E+06')
+ self.assertEqual(result, expected)
+
+ self.reset_display_options()
+
+ def compare(self, formatter, input, output):
+ formatted_input = formatter(input)
+ msg = ("formatting of %s results in '%s', expected '%s'" %
+ (str(input), formatted_input, output))
+ self.assertEqual(formatted_input, output, msg)
+
+ def compare_all(self, formatter, in_out):
+ """
+ Parameters:
+ -----------
+ formatter: EngFormatter under test
+ in_out: list of tuples. Each tuple = (number, expected_formatting)
+
+ It is tested if 'formatter(number) == expected_formatting'.
+ *number* should be >= 0 because formatter(-number) == fmt is also
+ tested. *fmt* is derived from *expected_formatting*
+ """
+ for input, output in in_out:
+ self.compare(formatter, input, output)
+ self.compare(formatter, -input, "-" + output[1:])
+
+ def test_exponents_with_eng_prefix(self):
+ formatter = fmt.EngFormatter(accuracy=3, use_eng_prefix=True)
+ f = np.sqrt(2)
+ in_out = [
+ (f * 10 ** -24, " 1.414y"), (f * 10 ** -23, " 14.142y"),
+ (f * 10 ** -22, " 141.421y"), (f * 10 ** -21, " 1.414z"),
+ (f * 10 ** -20, " 14.142z"), (f * 10 ** -19, " 141.421z"),
+ (f * 10 ** -18, " 1.414a"), (f * 10 ** -17, " 14.142a"),
+ (f * 10 ** -16, " 141.421a"), (f * 10 ** -15, " 1.414f"),
+ (f * 10 ** -14, " 14.142f"), (f * 10 ** -13, " 141.421f"),
+ (f * 10 ** -12, " 1.414p"), (f * 10 ** -11, " 14.142p"),
+ (f * 10 ** -10, " 141.421p"), (f * 10 ** -9, " 1.414n"),
+ (f * 10 ** -8, " 14.142n"), (f * 10 ** -7, " 141.421n"),
+ (f * 10 ** -6, " 1.414u"), (f * 10 ** -5, " 14.142u"),
+ (f * 10 ** -4, " 141.421u"), (f * 10 ** -3, " 1.414m"),
+ (f * 10 ** -2, " 14.142m"), (f * 10 ** -1, " 141.421m"),
+ (f * 10 ** 0, " 1.414"), (f * 10 ** 1, " 14.142"),
+ (f * 10 ** 2, " 141.421"), (f * 10 ** 3, " 1.414k"),
+ (f * 10 ** 4, " 14.142k"), (f * 10 ** 5, " 141.421k"),
+ (f * 10 ** 6, " 1.414M"), (f * 10 ** 7, " 14.142M"),
+ (f * 10 ** 8, " 141.421M"), (f * 10 ** 9, " 1.414G"),
+ (f * 10 ** 10, " 14.142G"), (f * 10 ** 11, " 141.421G"),
+ (f * 10 ** 12, " 1.414T"), (f * 10 ** 13, " 14.142T"),
+ (f * 10 ** 14, " 141.421T"), (f * 10 ** 15, " 1.414P"),
+ (f * 10 ** 16, " 14.142P"), (f * 10 ** 17, " 141.421P"),
+ (f * 10 ** 18, " 1.414E"), (f * 10 ** 19, " 14.142E"),
+ (f * 10 ** 20, " 141.421E"), (f * 10 ** 21, " 1.414Z"),
+ (f * 10 ** 22, " 14.142Z"), (f * 10 ** 23, " 141.421Z"),
+ (f * 10 ** 24, " 1.414Y"), (f * 10 ** 25, " 14.142Y"),
+ (f * 10 ** 26, " 141.421Y")]
+ self.compare_all(formatter, in_out)
+
+ def test_exponents_without_eng_prefix(self):
+ formatter = fmt.EngFormatter(accuracy=4, use_eng_prefix=False)
+ f = np.pi
+ in_out = [
+ (f * 10 ** -24, " 3.1416E-24"),
+ (f * 10 ** -23, " 31.4159E-24"),
+ (f * 10 ** -22, " 314.1593E-24"),
+ (f * 10 ** -21, " 3.1416E-21"),
+ (f * 10 ** -20, " 31.4159E-21"),
+ (f * 10 ** -19, " 314.1593E-21"),
+ (f * 10 ** -18, " 3.1416E-18"),
+ (f * 10 ** -17, " 31.4159E-18"),
+ (f * 10 ** -16, " 314.1593E-18"),
+ (f * 10 ** -15, " 3.1416E-15"),
+ (f * 10 ** -14, " 31.4159E-15"),
+ (f * 10 ** -13, " 314.1593E-15"),
+ (f * 10 ** -12, " 3.1416E-12"),
+ (f * 10 ** -11, " 31.4159E-12"),
+ (f * 10 ** -10, " 314.1593E-12"),
+ (f * 10 ** -9, " 3.1416E-09"),
+ (f * 10 ** -8, " 31.4159E-09"),
+ (f * 10 ** -7, " 314.1593E-09"),
+ (f * 10 ** -6, " 3.1416E-06"),
+ (f * 10 ** -5, " 31.4159E-06"),
+ (f * 10 ** -4, " 314.1593E-06"),
+ (f * 10 ** -3, " 3.1416E-03"),
+ (f * 10 ** -2, " 31.4159E-03"),
+ (f * 10 ** -1, " 314.1593E-03"),
+ (f * 10 ** 0, " 3.1416E+00"),
+ (f * 10 ** 1, " 31.4159E+00"),
+ (f * 10 ** 2, " 314.1593E+00"),
+ (f * 10 ** 3, " 3.1416E+03"),
+ (f * 10 ** 4, " 31.4159E+03"),
+ (f * 10 ** 5, " 314.1593E+03"),
+ (f * 10 ** 6, " 3.1416E+06"),
+ (f * 10 ** 7, " 31.4159E+06"),
+ (f * 10 ** 8, " 314.1593E+06"),
+ (f * 10 ** 9, " 3.1416E+09"),
+ (f * 10 ** 10, " 31.4159E+09"),
+ (f * 10 ** 11, " 314.1593E+09"),
+ (f * 10 ** 12, " 3.1416E+12"),
+ (f * 10 ** 13, " 31.4159E+12"),
+ (f * 10 ** 14, " 314.1593E+12"),
+ (f * 10 ** 15, " 3.1416E+15"),
+ (f * 10 ** 16, " 31.4159E+15"),
+ (f * 10 ** 17, " 314.1593E+15"),
+ (f * 10 ** 18, " 3.1416E+18"),
+ (f * 10 ** 19, " 31.4159E+18"),
+ (f * 10 ** 20, " 314.1593E+18"),
+ (f * 10 ** 21, " 3.1416E+21"),
+ (f * 10 ** 22, " 31.4159E+21"),
+ (f * 10 ** 23, " 314.1593E+21"),
+ (f * 10 ** 24, " 3.1416E+24"),
+ (f * 10 ** 25, " 31.4159E+24"),
+ (f * 10 ** 26, " 314.1593E+24")]
+ self.compare_all(formatter, in_out)
+
+ def test_rounding(self):
+ formatter = fmt.EngFormatter(accuracy=3, use_eng_prefix=True)
+ in_out = [(5.55555, ' 5.556'), (55.5555, ' 55.556'),
+ (555.555, ' 555.555'), (5555.55, ' 5.556k'),
+ (55555.5, ' 55.556k'), (555555, ' 555.555k')]
+ self.compare_all(formatter, in_out)
+
+ formatter = fmt.EngFormatter(accuracy=1, use_eng_prefix=True)
+ in_out = [(5.55555, ' 5.6'), (55.5555, ' 55.6'), (555.555, ' 555.6'),
+ (5555.55, ' 5.6k'), (55555.5, ' 55.6k'), (555555, ' 555.6k')]
+ self.compare_all(formatter, in_out)
+
+ formatter = fmt.EngFormatter(accuracy=0, use_eng_prefix=True)
+ in_out = [(5.55555, ' 6'), (55.5555, ' 56'), (555.555, ' 556'),
+ (5555.55, ' 6k'), (55555.5, ' 56k'), (555555, ' 556k')]
+ self.compare_all(formatter, in_out)
+
+ formatter = fmt.EngFormatter(accuracy=3, use_eng_prefix=True)
+ result = formatter(0)
+ self.assertEqual(result, u(' 0.000'))
+
+ def test_nan(self):
+ # Issue #11981
+
+ formatter = fmt.EngFormatter(accuracy=1, use_eng_prefix=True)
+ result = formatter(np.nan)
+ self.assertEqual(result, u('NaN'))
+
+ df = pd.DataFrame({'a': [1.5, 10.3, 20.5],
+ 'b': [50.3, 60.67, 70.12],
+ 'c': [100.2, 101.33, 120.33]})
+ pt = df.pivot_table(values='a', index='b', columns='c')
+ fmt.set_eng_float_format(accuracy=1)
+ result = pt.to_string()
+ self.assertTrue('NaN' in result)
+ self.reset_display_options()
+
+ def test_inf(self):
+ # Issue #11981
+
+ formatter = fmt.EngFormatter(accuracy=1, use_eng_prefix=True)
+ result = formatter(np.inf)
+ self.assertEqual(result, u('inf'))
diff --git a/pandas/tests/formats/test_format.py b/pandas/tests/formats/test_format.py
index 476c6a636ae5a..ddf9d35841ce7 100644
--- a/pandas/tests/formats/test_format.py
+++ b/pandas/tests/formats/test_format.py
@@ -1,50 +1,41 @@
# -*- coding: utf-8 -*-
+"""
+test output formatting for Series/DataFrame
+including to_string & reprs
+"""
+
# TODO(wesm): lots of issues making flake8 hard
# flake8: noqa
from __future__ import print_function
-from distutils.version import LooseVersion
import re
-from pandas.compat import (range, zip, lrange, StringIO, PY3,
- u, lzip, is_platform_windows,
- is_platform_32bit)
-import pandas.compat as compat
import itertools
from operator import methodcaller
import os
import sys
-from textwrap import dedent
import warnings
+from datetime import datetime
-from numpy import nan
-from numpy.random import randn
-import numpy as np
-
-import codecs
-
-div_style = ''
-try:
- import IPython
- if IPython.__version__ < LooseVersion('3.0.0'):
- div_style = ' style="max-width:1500px;overflow:auto;"'
-except (ImportError, AttributeError):
- pass
+import pytest
-from pandas import DataFrame, Series, Index, Timestamp, MultiIndex, date_range, NaT
+import numpy as np
+import pandas as pd
+from pandas import (DataFrame, Series, Index, Timestamp, MultiIndex,
+ date_range, NaT, read_table)
+from pandas.compat import (range, zip, lrange, StringIO, PY3,
+ u, lzip, is_platform_windows,
+ is_platform_32bit)
+import pandas.compat as compat
import pandas.formats.format as fmt
-import pandas.util.testing as tm
-import pandas.core.common as com
import pandas.formats.printing as printing
+
+import pandas.util.testing as tm
from pandas.util.terminal import get_terminal_size
-import pandas as pd
from pandas.core.config import (set_option, get_option, option_context,
reset_option)
-from datetime import datetime
-
-import pytest
use_32bit_repr = is_platform_windows() or is_platform_32bit()
@@ -288,7 +279,7 @@ def test_repr_max_columns_max_rows(self):
term_width, term_height = get_terminal_size()
if term_width < 10 or term_height < 10:
pytest.skip("terminal size too small, "
- "{0} x {1}".format(term_width, term_height))
+ "{0} x {1}".format(term_width, term_height))
def mkframe(n):
index = ['%05d' % i for i in range(n)]
@@ -829,1393 +820,6 @@ def test_datetimelike_frame(self):
'[10 rows x 2 columns]')
self.assertEqual(repr(df), expected)
- def test_to_html_with_col_space(self):
- def check_with_width(df, col_space):
- import re
- # check that col_space affects HTML generation
- # and be very brittle about it.
- html = df.to_html(col_space=col_space)
- hdrs = [x for x in html.split(r"\n") if re.search(r"
\s]", x)]
- self.assertTrue(len(hdrs) > 0)
- for h in hdrs:
- self.assertTrue("min-width" in h)
- self.assertTrue(str(col_space) in h)
-
- df = DataFrame(np.random.random(size=(1, 3)))
-
- check_with_width(df, 30)
- check_with_width(df, 50)
-
- def test_to_html_with_empty_string_label(self):
- # GH3547, to_html regards empty string labels as repeated labels
- data = {'c1': ['a', 'b'], 'c2': ['a', ''], 'data': [1, 2]}
- df = DataFrame(data).set_index(['c1', 'c2'])
- res = df.to_html()
- self.assertTrue("rowspan" not in res)
-
- def test_to_html_unicode(self):
- df = DataFrame({u('\u03c3'): np.arange(10.)})
- expected = u'\n \n \n | \n \u03c3 | \n \n \n \n \n 0 | \n 0.0 | \n \n \n 1 | \n 1.0 | \n \n \n 2 | \n 2.0 | \n \n \n 3 | \n 3.0 | \n \n \n 4 | \n 4.0 | \n \n \n 5 | \n 5.0 | \n \n \n 6 | \n 6.0 | \n \n \n 7 | \n 7.0 | \n \n \n 8 | \n 8.0 | \n \n \n 9 | \n 9.0 | \n \n \n '
- self.assertEqual(df.to_html(), expected)
- df = DataFrame({'A': [u('\u03c3')]})
- expected = u'\n \n \n | \n A | \n \n \n \n \n 0 | \n \u03c3 | \n \n \n '
- self.assertEqual(df.to_html(), expected)
-
- def test_to_html_decimal(self):
- # GH 12031
- df = DataFrame({'A': [6.0, 3.1, 2.2]})
- result = df.to_html(decimal=',')
- expected = ('\n'
- ' \n'
- ' \n'
- ' | \n'
- ' A | \n'
- ' \n'
- ' \n'
- ' \n'
- ' \n'
- ' 0 | \n'
- ' 6,0 | \n'
- ' \n'
- ' \n'
- ' 1 | \n'
- ' 3,1 | \n'
- ' \n'
- ' \n'
- ' 2 | \n'
- ' 2,2 | \n'
- ' \n'
- ' \n'
- ' ')
- self.assertEqual(result, expected)
-
- def test_to_html_escaped(self):
- a = 'str",
- b: ""},
- 'co>l2': {a: "",
- b: ""}}
- rs = DataFrame(test_dict).to_html()
- xp = """
-
-
- |
- co<l1 |
- co>l2 |
-
-
-
-
- str<ing1 & |
- <type 'str'> |
- <type 'str'> |
-
-
- stri>ng2 & |
- <type 'str'> |
- <type 'str'> |
-
-
- """
-
- self.assertEqual(xp, rs)
-
- def test_to_html_escape_disabled(self):
- a = 'strbold",
- b: "bold"},
- 'co>l2': {a: "bold",
- b: "bold"}}
- rs = DataFrame(test_dict).to_html(escape=False)
- xp = """
-
-
- |
- co
- co>l2 |
- |
-
-
-
- str
- bold |
- bold |
- |
-
- stri>ng2 & |
- bold |
- bold |
-
-
- """
-
- self.assertEqual(xp, rs)
-
- def test_to_html_multiindex_index_false(self):
- # issue 8452
- df = DataFrame({
- 'a': range(2),
- 'b': range(3, 5),
- 'c': range(5, 7),
- 'd': range(3, 5)
- })
- df.columns = MultiIndex.from_product([['a', 'b'], ['c', 'd']])
- result = df.to_html(index=False)
- expected = """\
-
-
-
- a |
- b |
-
-
- c |
- d |
- c |
- d |
-
-
-
-
- 0 |
- 3 |
- 5 |
- 3 |
-
-
- 1 |
- 4 |
- 6 |
- 4 |
-
-
- """
-
- self.assertEqual(result, expected)
-
- df.index = Index(df.index.values, name='idx')
- result = df.to_html(index=False)
- self.assertEqual(result, expected)
-
- def test_to_html_multiindex_sparsify_false_multi_sparse(self):
- with option_context('display.multi_sparse', False):
- index = MultiIndex.from_arrays([[0, 0, 1, 1], [0, 1, 0, 1]],
- names=['foo', None])
-
- df = DataFrame([[0, 1], [2, 3], [4, 5], [6, 7]], index=index)
-
- result = df.to_html()
- expected = """\
-
-
-
- |
- |
- 0 |
- 1 |
-
-
- foo |
- |
- |
- |
-
-
-
-
- 0 |
- 0 |
- 0 |
- 1 |
-
-
- 0 |
- 1 |
- 2 |
- 3 |
-
-
- 1 |
- 0 |
- 4 |
- 5 |
-
-
- 1 |
- 1 |
- 6 |
- 7 |
-
-
- """
-
- self.assertEqual(result, expected)
-
- df = DataFrame([[0, 1], [2, 3], [4, 5], [6, 7]],
- columns=index[::2], index=index)
-
- result = df.to_html()
- expected = """\
-
-
-
- |
- foo |
- 0 |
- 1 |
-
-
- |
- |
- 0 |
- 0 |
-
-
- foo |
- |
- |
- |
-
-
-
-
- 0 |
- 0 |
- 0 |
- 1 |
-
-
- 0 |
- 1 |
- 2 |
- 3 |
-
-
- 1 |
- 0 |
- 4 |
- 5 |
-
-
- 1 |
- 1 |
- 6 |
- 7 |
-
-
- """
-
- self.assertEqual(result, expected)
-
- def test_to_html_multiindex_sparsify(self):
- index = MultiIndex.from_arrays([[0, 0, 1, 1], [0, 1, 0, 1]],
- names=['foo', None])
-
- df = DataFrame([[0, 1], [2, 3], [4, 5], [6, 7]], index=index)
-
- result = df.to_html()
- expected = """
-
-
- |
- |
- 0 |
- 1 |
-
-
- foo |
- |
- |
- |
-
-
-
-
- 0 |
- 0 |
- 0 |
- 1 |
-
-
- 1 |
- 2 |
- 3 |
-
-
- 1 |
- 0 |
- 4 |
- 5 |
-
-
- 1 |
- 6 |
- 7 |
-
-
- """
-
- self.assertEqual(result, expected)
-
- df = DataFrame([[0, 1], [2, 3], [4, 5], [6, 7]], columns=index[::2],
- index=index)
-
- result = df.to_html()
- expected = """\
-
-
-
- |
- foo |
- 0 |
- 1 |
-
-
- |
- |
- 0 |
- 0 |
-
-
- foo |
- |
- |
- |
-
-
-
-
- 0 |
- 0 |
- 0 |
- 1 |
-
-
- 1 |
- 2 |
- 3 |
-
-
- 1 |
- 0 |
- 4 |
- 5 |
-
-
- 1 |
- 6 |
- 7 |
-
-
- """
-
- self.assertEqual(result, expected)
-
- def test_to_html_multiindex_odd_even_truncate(self):
- # GH 14882 - Issue on truncation with odd length DataFrame
- mi = MultiIndex.from_product([[100, 200, 300],
- [10, 20, 30],
- [1, 2, 3, 4, 5, 6, 7]],
- names=['a', 'b', 'c'])
- df = DataFrame({'n': range(len(mi))}, index=mi)
- result = df.to_html(max_rows=60)
- expected = """\
-
-
-
- |
- |
- |
- n |
-
-
- a |
- b |
- c |
- |
-
-
-
-
- 100 |
- 10 |
- 1 |
- 0 |
-
-
- 2 |
- 1 |
-
-
- 3 |
- 2 |
-
-
- 4 |
- 3 |
-
-
- 5 |
- 4 |
-
-
- 6 |
- 5 |
-
-
- 7 |
- 6 |
-
-
- 20 |
- 1 |
- 7 |
-
-
- 2 |
- 8 |
-
-
- 3 |
- 9 |
-
-
- 4 |
- 10 |
-
-
- 5 |
- 11 |
-
-
- 6 |
- 12 |
-
-
- 7 |
- 13 |
-
-
- 30 |
- 1 |
- 14 |
-
-
- 2 |
- 15 |
-
-
- 3 |
- 16 |
-
-
- 4 |
- 17 |
-
-
- 5 |
- 18 |
-
-
- 6 |
- 19 |
-
-
- 7 |
- 20 |
-
-
- 200 |
- 10 |
- 1 |
- 21 |
-
-
- 2 |
- 22 |
-
-
- 3 |
- 23 |
-
-
- 4 |
- 24 |
-
-
- 5 |
- 25 |
-
-
- 6 |
- 26 |
-
-
- 7 |
- 27 |
-
-
- 20 |
- 1 |
- 28 |
-
-
- 2 |
- 29 |
-
-
- ... |
- ... |
-
-
- 6 |
- 33 |
-
-
- 7 |
- 34 |
-
-
- 30 |
- 1 |
- 35 |
-
-
- 2 |
- 36 |
-
-
- 3 |
- 37 |
-
-
- 4 |
- 38 |
-
-
- 5 |
- 39 |
-
-
- 6 |
- 40 |
-
-
- 7 |
- 41 |
-
-
- 300 |
- 10 |
- 1 |
- 42 |
-
-
- 2 |
- 43 |
-
-
- 3 |
- 44 |
-
-
- 4 |
- 45 |
-
-
- 5 |
- 46 |
-
-
- 6 |
- 47 |
-
-
- 7 |
- 48 |
-
-
- 20 |
- 1 |
- 49 |
-
-
- 2 |
- 50 |
-
-
- 3 |
- 51 |
-
-
- 4 |
- 52 |
-
-
- 5 |
- 53 |
-
-
- 6 |
- 54 |
-
-
- 7 |
- 55 |
-
-
- 30 |
- 1 |
- 56 |
-
-
- 2 |
- 57 |
-
-
- 3 |
- 58 |
-
-
- 4 |
- 59 |
-
-
- 5 |
- 60 |
-
-
- 6 |
- 61 |
-
-
- 7 |
- 62 |
-
-
- """
- self.assertEqual(result, expected)
-
- # Test that ... appears in a middle level
- result = df.to_html(max_rows=56)
- expected = """\
-
-
-
- |
- |
- |
- n |
-
-
- a |
- b |
- c |
- |
-
-
-
-
- 100 |
- 10 |
- 1 |
- 0 |
-
-
- 2 |
- 1 |
-
-
- 3 |
- 2 |
-
-
- 4 |
- 3 |
-
-
- 5 |
- 4 |
-
-
- 6 |
- 5 |
-
-
- 7 |
- 6 |
-
-
- 20 |
- 1 |
- 7 |
-
-
- 2 |
- 8 |
-
-
- 3 |
- 9 |
-
-
- 4 |
- 10 |
-
-
- 5 |
- 11 |
-
-
- 6 |
- 12 |
-
-
- 7 |
- 13 |
-
-
- 30 |
- 1 |
- 14 |
-
-
- 2 |
- 15 |
-
-
- 3 |
- 16 |
-
-
- 4 |
- 17 |
-
-
- 5 |
- 18 |
-
-
- 6 |
- 19 |
-
-
- 7 |
- 20 |
-
-
- 200 |
- 10 |
- 1 |
- 21 |
-
-
- 2 |
- 22 |
-
-
- 3 |
- 23 |
-
-
- 4 |
- 24 |
-
-
- 5 |
- 25 |
-
-
- 6 |
- 26 |
-
-
- 7 |
- 27 |
-
-
- ... |
- ... |
- ... |
-
-
- 30 |
- 1 |
- 35 |
-
-
- 2 |
- 36 |
-
-
- 3 |
- 37 |
-
-
- 4 |
- 38 |
-
-
- 5 |
- 39 |
-
-
- 6 |
- 40 |
-
-
- 7 |
- 41 |
-
-
- 300 |
- 10 |
- 1 |
- 42 |
-
-
- 2 |
- 43 |
-
-
- 3 |
- 44 |
-
-
- 4 |
- 45 |
-
-
- 5 |
- 46 |
-
-
- 6 |
- 47 |
-
-
- 7 |
- 48 |
-
-
- 20 |
- 1 |
- 49 |
-
-
- 2 |
- 50 |
-
-
- 3 |
- 51 |
-
-
- 4 |
- 52 |
-
-
- 5 |
- 53 |
-
-
- 6 |
- 54 |
-
-
- 7 |
- 55 |
-
-
- 30 |
- 1 |
- 56 |
-
-
- 2 |
- 57 |
-
-
- 3 |
- 58 |
-
-
- 4 |
- 59 |
-
-
- 5 |
- 60 |
-
-
- 6 |
- 61 |
-
-
- 7 |
- 62 |
-
-
- """
- self.assertEqual(result, expected)
-
- def test_to_html_index_formatter(self):
- df = DataFrame([[0, 1], [2, 3], [4, 5], [6, 7]], columns=['foo', None],
- index=lrange(4))
-
- f = lambda x: 'abcd' [x]
- result = df.to_html(formatters={'__index__': f})
- expected = """\
-
-
-
- |
- foo |
- None |
-
-
-
-
- a |
- 0 |
- 1 |
-
-
- b |
- 2 |
- 3 |
-
-
- c |
- 4 |
- 5 |
-
-
- d |
- 6 |
- 7 |
-
-
- """
-
- self.assertEqual(result, expected)
-
- def test_to_html_datetime64_monthformatter(self):
- months = [datetime(2016, 1, 1), datetime(2016, 2, 2)]
- x = DataFrame({'months': months})
-
- def format_func(x):
- return x.strftime('%Y-%m')
- result = x.to_html(formatters={'months': format_func})
- expected = """\
-
-
-
- |
- months |
-
-
-
-
- 0 |
- 2016-01 |
-
-
- 1 |
- 2016-02 |
-
-
- """
- self.assertEqual(result, expected)
-
- def test_to_html_datetime64_hourformatter(self):
-
- x = DataFrame({'hod': pd.to_datetime(['10:10:10.100', '12:12:12.120'],
- format='%H:%M:%S.%f')})
-
- def format_func(x):
- return x.strftime('%H:%M')
- result = x.to_html(formatters={'hod': format_func})
- expected = """\
-
-
-
- |
- hod |
-
-
-
-
- 0 |
- 10:10 |
-
-
- 1 |
- 12:12 |
-
-
- """
- self.assertEqual(result, expected)
-
- def test_to_html_regression_GH6098(self):
- df = DataFrame({u('clé1'): [u('a'), u('a'), u('b'), u('b'), u('a')],
- u('clé2'): [u('1er'), u('2ème'), u('1er'), u('2ème'),
- u('1er')],
- 'données1': np.random.randn(5),
- 'données2': np.random.randn(5)})
- # it works
- df.pivot_table(index=[u('clé1')], columns=[u('clé2')])._repr_html_()
-
- def test_to_html_truncate(self):
- pytest.skip("unreliable on travis")
- index = pd.DatetimeIndex(start='20010101', freq='D', periods=20)
- df = DataFrame(index=index, columns=range(20))
- fmt.set_option('display.max_rows', 8)
- fmt.set_option('display.max_columns', 4)
- result = df._repr_html_()
- expected = '''\
-
-
-
-
- |
- 0 |
- 1 |
- ... |
- 18 |
- 19 |
-
-
-
-
- 2001-01-01 |
- NaN |
- NaN |
- ... |
- NaN |
- NaN |
-
-
- 2001-01-02 |
- NaN |
- NaN |
- ... |
- NaN |
- NaN |
-
-
- 2001-01-03 |
- NaN |
- NaN |
- ... |
- NaN |
- NaN |
-
-
- 2001-01-04 |
- NaN |
- NaN |
- ... |
- NaN |
- NaN |
-
-
- ... |
- ... |
- ... |
- ... |
- ... |
- ... |
-
-
- 2001-01-17 |
- NaN |
- NaN |
- ... |
- NaN |
- NaN |
-
-
- 2001-01-18 |
- NaN |
- NaN |
- ... |
- NaN |
- NaN |
-
-
- 2001-01-19 |
- NaN |
- NaN |
- ... |
- NaN |
- NaN |
-
-
- 2001-01-20 |
- NaN |
- NaN |
- ... |
- NaN |
- NaN |
-
-
-
- 20 rows × 20 columns
- '''.format(div_style)
- if compat.PY2:
- expected = expected.decode('utf-8')
- self.assertEqual(result, expected)
-
- def test_to_html_truncate_multi_index(self):
- pytest.skip("unreliable on travis")
- arrays = [['bar', 'bar', 'baz', 'baz', 'foo', 'foo', 'qux', 'qux'],
- ['one', 'two', 'one', 'two', 'one', 'two', 'one', 'two']]
- df = DataFrame(index=arrays, columns=arrays)
- fmt.set_option('display.max_rows', 7)
- fmt.set_option('display.max_columns', 7)
- result = df._repr_html_()
- expected = '''\
-
-
-
-
- |
- |
- bar |
- baz |
- ... |
- foo |
- qux |
-
-
- |
- |
- one |
- two |
- one |
- ... |
- two |
- one |
- two |
-
-
-
-
- bar |
- one |
- NaN |
- NaN |
- NaN |
- ... |
- NaN |
- NaN |
- NaN |
-
-
- two |
- NaN |
- NaN |
- NaN |
- ... |
- NaN |
- NaN |
- NaN |
-
-
- baz |
- one |
- NaN |
- NaN |
- NaN |
- ... |
- NaN |
- NaN |
- NaN |
-
-
- ... |
- ... |
- ... |
- ... |
- ... |
- ... |
- ... |
- ... |
- ... |
-
-
- foo |
- two |
- NaN |
- NaN |
- NaN |
- ... |
- NaN |
- NaN |
- NaN |
-
-
- qux |
- one |
- NaN |
- NaN |
- NaN |
- ... |
- NaN |
- NaN |
- NaN |
-
-
- two |
- NaN |
- NaN |
- NaN |
- ... |
- NaN |
- NaN |
- NaN |
-
-
-
- 8 rows × 8 columns
- '''.format(div_style)
- if compat.PY2:
- expected = expected.decode('utf-8')
- self.assertEqual(result, expected)
-
- def test_to_html_truncate_multi_index_sparse_off(self):
- pytest.skip("unreliable on travis")
- arrays = [['bar', 'bar', 'baz', 'baz', 'foo', 'foo', 'qux', 'qux'],
- ['one', 'two', 'one', 'two', 'one', 'two', 'one', 'two']]
- df = DataFrame(index=arrays, columns=arrays)
- fmt.set_option('display.max_rows', 7)
- fmt.set_option('display.max_columns', 7)
- fmt.set_option('display.multi_sparse', False)
- result = df._repr_html_()
- expected = '''\
-
-
-
-
- |
- |
- bar |
- bar |
- baz |
- ... |
- foo |
- qux |
- qux |
-
-
- |
- |
- one |
- two |
- one |
- ... |
- two |
- one |
- two |
-
-
-
-
- bar |
- one |
- NaN |
- NaN |
- NaN |
- ... |
- NaN |
- NaN |
- NaN |
-
-
- bar |
- two |
- NaN |
- NaN |
- NaN |
- ... |
- NaN |
- NaN |
- NaN |
-
-
- baz |
- one |
- NaN |
- NaN |
- NaN |
- ... |
- NaN |
- NaN |
- NaN |
-
-
- foo |
- two |
- NaN |
- NaN |
- NaN |
- ... |
- NaN |
- NaN |
- NaN |
-
-
- qux |
- one |
- NaN |
- NaN |
- NaN |
- ... |
- NaN |
- NaN |
- NaN |
-
-
- qux |
- two |
- NaN |
- NaN |
- NaN |
- ... |
- NaN |
- NaN |
- NaN |
-
-
-
- 8 rows × 8 columns
- '''.format(div_style)
- if compat.PY2:
- expected = expected.decode('utf-8')
- self.assertEqual(result, expected)
-
- def test_to_html_border(self):
- df = DataFrame({'A': [1, 2]})
- result = df.to_html()
- assert 'border="1"' in result
-
- def test_to_html_border_option(self):
- df = DataFrame({'A': [1, 2]})
- with pd.option_context('html.border', 0):
- result = df.to_html()
- self.assertTrue('border="0"' in result)
- self.assertTrue('border="0"' in df._repr_html_())
-
- def test_to_html_border_zero(self):
- df = DataFrame({'A': [1, 2]})
- result = df.to_html(border=0)
- self.assertTrue('border="0"' in result)
-
def test_nonunicode_nonascii_alignment(self):
df = DataFrame([["aa\xc3\xa4\xc3\xa4", 1], ["bbbb", 2]])
rep_str = df.to_string()
@@ -2223,7 +827,7 @@ def test_nonunicode_nonascii_alignment(self):
self.assertEqual(len(lines[1]), len(lines[2]))
def test_unicode_problem_decoding_as_ascii(self):
- dm = DataFrame({u('c/\u03c3'): Series({'test': np.NaN})})
+ dm = DataFrame({u('c/\u03c3'): Series({'test': np.nan})})
compat.text_type(dm.to_string())
def test_string_repr_encoding(self):
@@ -2271,7 +875,7 @@ def test_pprint_thing(self):
# escape embedded tabs in string
# GH #2038
- self.assertTrue(not "\t" in pp_t("a\tb", escape_chars=("\t", )))
+ assert "\t" not in pp_t("a\tb", escape_chars=("\t", ))
def test_wide_repr(self):
with option_context('mode.sim_interactive', True,
@@ -2294,7 +898,8 @@ def test_wide_repr(self):
def test_wide_repr_wide_columns(self):
with option_context('mode.sim_interactive', True):
- df = DataFrame(randn(5, 3), columns=['a' * 90, 'b' * 90, 'c' * 90])
+ df = DataFrame(np.random.randn(5, 3),
+ columns=['a' * 90, 'b' * 90, 'c' * 90])
rep_str = repr(df)
self.assertEqual(len(rep_str.splitlines()), 20)
@@ -2346,8 +951,8 @@ def test_wide_repr_multiindex_cols(self):
with option_context('mode.sim_interactive', True):
max_cols = get_option('display.max_columns')
midx = MultiIndex.from_arrays(tm.rands_array(5, size=(2, 10)))
- mcols = MultiIndex.from_arrays(tm.rands_array(3, size=(2, max_cols
- - 1)))
+ mcols = MultiIndex.from_arrays(
+ tm.rands_array(3, size=(2, max_cols - 1)))
df = DataFrame(tm.rands_array(25, (10, max_cols - 1)),
index=midx, columns=mcols)
df.index.names = ['Level 0', 'Level 1']
@@ -2465,16 +1070,14 @@ def test_index_with_nan(self):
self.assertEqual(result, expected)
def test_to_string(self):
- from pandas import read_table
- import re
# big mixed
- biggie = DataFrame({'A': randn(200),
+ biggie = DataFrame({'A': np.random.randn(200),
'B': tm.makeStringIndex(200)},
index=lrange(200))
- biggie.loc[:20, 'A'] = nan
- biggie.loc[:20, 'B'] = nan
+ biggie.loc[:20, 'A'] = np.nan
+ biggie.loc[:20, 'B'] = np.nan
s = biggie.to_string()
buf = StringIO()
@@ -2713,414 +1316,6 @@ def test_show_dimensions(self):
self.assertFalse('5 rows' in str(df))
self.assertFalse('5 rows' in df._repr_html_())
- def test_to_html(self):
- # big mixed
- biggie = DataFrame({'A': randn(200),
- 'B': tm.makeStringIndex(200)},
- index=lrange(200))
-
- biggie.loc[:20, 'A'] = nan
- biggie.loc[:20, 'B'] = nan
- s = biggie.to_html()
-
- buf = StringIO()
- retval = biggie.to_html(buf=buf)
- self.assertIsNone(retval)
- self.assertEqual(buf.getvalue(), s)
-
- tm.assertIsInstance(s, compat.string_types)
-
- biggie.to_html(columns=['B', 'A'], col_space=17)
- biggie.to_html(columns=['B', 'A'],
- formatters={'A': lambda x: '%.1f' % x})
-
- biggie.to_html(columns=['B', 'A'], float_format=str)
- biggie.to_html(columns=['B', 'A'], col_space=12, float_format=str)
-
- frame = DataFrame(index=np.arange(200))
- frame.to_html()
-
- def test_to_html_filename(self):
- biggie = DataFrame({'A': randn(200),
- 'B': tm.makeStringIndex(200)},
- index=lrange(200))
-
- biggie.loc[:20, 'A'] = nan
- biggie.loc[:20, 'B'] = nan
- with tm.ensure_clean('test.html') as path:
- biggie.to_html(path)
- with open(path, 'r') as f:
- s = biggie.to_html()
- s2 = f.read()
- self.assertEqual(s, s2)
-
- frame = DataFrame(index=np.arange(200))
- with tm.ensure_clean('test.html') as path:
- frame.to_html(path)
- with open(path, 'r') as f:
- self.assertEqual(frame.to_html(), f.read())
-
- def test_to_html_with_no_bold(self):
- x = DataFrame({'x': randn(5)})
- ashtml = x.to_html(bold_rows=False)
- self.assertFalse('")])
-
- def test_to_html_columns_arg(self):
- result = self.frame.to_html(columns=['A'])
- self.assertNotIn('B | ', result)
-
- def test_to_html_multiindex(self):
- columns = MultiIndex.from_tuples(list(zip(np.arange(2).repeat(2),
- np.mod(lrange(4), 2))),
- names=['CL0', 'CL1'])
- df = DataFrame([list('abcd'), list('efgh')], columns=columns)
- result = df.to_html(justify='left')
- expected = ('\n'
- ' \n'
- ' \n'
- ' CL0 | \n'
- ' 0 | \n'
- ' 1 | \n'
- ' \n'
- ' \n'
- ' CL1 | \n'
- ' 0 | \n'
- ' 1 | \n'
- ' 0 | \n'
- ' 1 | \n'
- ' \n'
- ' \n'
- ' \n'
- ' \n'
- ' 0 | \n'
- ' a | \n'
- ' b | \n'
- ' c | \n'
- ' d | \n'
- ' \n'
- ' \n'
- ' 1 | \n'
- ' e | \n'
- ' f | \n'
- ' g | \n'
- ' h | \n'
- ' \n'
- ' \n'
- ' ')
-
- self.assertEqual(result, expected)
-
- columns = MultiIndex.from_tuples(list(zip(
- range(4), np.mod(
- lrange(4), 2))))
- df = DataFrame([list('abcd'), list('efgh')], columns=columns)
-
- result = df.to_html(justify='right')
- expected = ('\n'
- ' \n'
- ' \n'
- ' | \n'
- ' 0 | \n'
- ' 1 | \n'
- ' 2 | \n'
- ' 3 | \n'
- ' \n'
- ' \n'
- ' | \n'
- ' 0 | \n'
- ' 1 | \n'
- ' 0 | \n'
- ' 1 | \n'
- ' \n'
- ' \n'
- ' \n'
- ' \n'
- ' 0 | \n'
- ' a | \n'
- ' b | \n'
- ' c | \n'
- ' d | \n'
- ' \n'
- ' \n'
- ' 1 | \n'
- ' e | \n'
- ' f | \n'
- ' g | \n'
- ' h | \n'
- ' \n'
- ' \n'
- ' ')
-
- self.assertEqual(result, expected)
-
- def test_to_html_justify(self):
- df = DataFrame({'A': [6, 30000, 2],
- 'B': [1, 2, 70000],
- 'C': [223442, 0, 1]},
- columns=['A', 'B', 'C'])
- result = df.to_html(justify='left')
- expected = ('\n'
- ' \n'
- ' \n'
- ' | \n'
- ' A | \n'
- ' B | \n'
- ' C | \n'
- ' \n'
- ' \n'
- ' \n'
- ' \n'
- ' 0 | \n'
- ' 6 | \n'
- ' 1 | \n'
- ' 223442 | \n'
- ' \n'
- ' \n'
- ' 1 | \n'
- ' 30000 | \n'
- ' 2 | \n'
- ' 0 | \n'
- ' \n'
- ' \n'
- ' 2 | \n'
- ' 2 | \n'
- ' 70000 | \n'
- ' 1 | \n'
- ' \n'
- ' \n'
- ' ')
- self.assertEqual(result, expected)
-
- result = df.to_html(justify='right')
- expected = ('\n'
- ' \n'
- ' \n'
- ' | \n'
- ' A | \n'
- ' B | \n'
- ' C | \n'
- ' \n'
- ' \n'
- ' \n'
- ' \n'
- ' 0 | \n'
- ' 6 | \n'
- ' 1 | \n'
- ' 223442 | \n'
- ' \n'
- ' \n'
- ' 1 | \n'
- ' 30000 | \n'
- ' 2 | \n'
- ' 0 | \n'
- ' \n'
- ' \n'
- ' 2 | \n'
- ' 2 | \n'
- ' 70000 | \n'
- ' 1 | \n'
- ' \n'
- ' \n'
- ' ')
- self.assertEqual(result, expected)
-
- def test_to_html_index(self):
- index = ['foo', 'bar', 'baz']
- df = DataFrame({'A': [1, 2, 3],
- 'B': [1.2, 3.4, 5.6],
- 'C': ['one', 'two', np.NaN]},
- columns=['A', 'B', 'C'],
- index=index)
- expected_with_index = ('\n'
- ' \n'
- ' \n'
- ' | \n'
- ' A | \n'
- ' B | \n'
- ' C | \n'
- ' \n'
- ' \n'
- ' \n'
- ' \n'
- ' foo | \n'
- ' 1 | \n'
- ' 1.2 | \n'
- ' one | \n'
- ' \n'
- ' \n'
- ' bar | \n'
- ' 2 | \n'
- ' 3.4 | \n'
- ' two | \n'
- ' \n'
- ' \n'
- ' baz | \n'
- ' 3 | \n'
- ' 5.6 | \n'
- ' NaN | \n'
- ' \n'
- ' \n'
- ' ')
- self.assertEqual(df.to_html(), expected_with_index)
-
- expected_without_index = ('\n'
- ' \n'
- ' \n'
- ' A | \n'
- ' B | \n'
- ' C | \n'
- ' \n'
- ' \n'
- ' \n'
- ' \n'
- ' 1 | \n'
- ' 1.2 | \n'
- ' one | \n'
- ' \n'
- ' \n'
- ' 2 | \n'
- ' 3.4 | \n'
- ' two | \n'
- ' \n'
- ' \n'
- ' 3 | \n'
- ' 5.6 | \n'
- ' NaN | \n'
- ' \n'
- ' \n'
- ' ')
- result = df.to_html(index=False)
- for i in index:
- self.assertNotIn(i, result)
- self.assertEqual(result, expected_without_index)
- df.index = Index(['foo', 'bar', 'baz'], name='idx')
- expected_with_index = ('\n'
- ' \n'
- ' \n'
- ' | \n'
- ' A | \n'
- ' B | \n'
- ' C | \n'
- ' \n'
- ' \n'
- ' idx | \n'
- ' | \n'
- ' | \n'
- ' | \n'
- ' \n'
- ' \n'
- ' \n'
- ' \n'
- ' foo | \n'
- ' 1 | \n'
- ' 1.2 | \n'
- ' one | \n'
- ' \n'
- ' \n'
- ' bar | \n'
- ' 2 | \n'
- ' 3.4 | \n'
- ' two | \n'
- ' \n'
- ' \n'
- ' baz | \n'
- ' 3 | \n'
- ' 5.6 | \n'
- ' NaN | \n'
- ' \n'
- ' \n'
- ' ')
- self.assertEqual(df.to_html(), expected_with_index)
- self.assertEqual(df.to_html(index=False), expected_without_index)
-
- tuples = [('foo', 'car'), ('foo', 'bike'), ('bar', 'car')]
- df.index = MultiIndex.from_tuples(tuples)
-
- expected_with_index = ('\n'
- ' \n'
- ' \n'
- ' | \n'
- ' | \n'
- ' A | \n'
- ' B | \n'
- ' C | \n'
- ' \n'
- ' \n'
- ' \n'
- ' \n'
- ' foo | \n'
- ' car | \n'
- ' 1 | \n'
- ' 1.2 | \n'
- ' one | \n'
- ' \n'
- ' \n'
- ' bike | \n'
- ' 2 | \n'
- ' 3.4 | \n'
- ' two | \n'
- ' \n'
- ' \n'
- ' bar | \n'
- ' car | \n'
- ' 3 | \n'
- ' 5.6 | \n'
- ' NaN | \n'
- ' \n'
- ' \n'
- ' ')
- self.assertEqual(df.to_html(), expected_with_index)
-
- result = df.to_html(index=False)
- for i in ['foo', 'bar', 'car', 'bike']:
- self.assertNotIn(i, result)
- # must be the same result as normal index
- self.assertEqual(result, expected_without_index)
-
- df.index = MultiIndex.from_tuples(tuples, names=['idx1', 'idx2'])
- expected_with_index = ('\n'
- ' \n'
- ' \n'
- ' | \n'
- ' | \n'
- ' A | \n'
- ' B | \n'
- ' C | \n'
- ' \n'
- ' \n'
- ' idx1 | \n'
- ' idx2 | \n'
- ' | \n'
- ' | \n'
- ' | \n'
- ' \n'
- ' \n'
- ' \n'
- ' \n'
- ' foo | \n'
- ' car | \n'
- ' 1 | \n'
- ' 1.2 | \n'
- ' one | \n'
- ' \n'
- ' \n'
- ' bike | \n'
- ' 2 | \n'
- ' 3.4 | \n'
- ' two | \n'
- ' \n'
- ' \n'
- ' bar | \n'
- ' car | \n'
- ' 3 | \n'
- ' 5.6 | \n'
- ' NaN | \n'
- ' \n'
- ' \n'
- ' ')
- self.assertEqual(df.to_html(), expected_with_index)
- self.assertEqual(df.to_html(index=False), expected_without_index)
-
def test_repr_html(self):
self.frame._repr_html_()
@@ -3254,7 +1449,7 @@ def test_info_repr(self):
def test_info_repr_max_cols(self):
# GH #6939
- df = DataFrame(randn(10, 5))
+ df = DataFrame(np.random.randn(10, 5))
with option_context('display.large_repr', 'info',
'display.max_columns', 1,
'display.max_info_columns', 4):
@@ -3299,46 +1494,6 @@ def get_ipython():
self.reset_display_options()
- def test_to_html_with_classes(self):
- df = DataFrame()
- result = df.to_html(classes="sortable draggable")
- expected = dedent("""
-
-
-
- """).strip()
- self.assertEqual(result, expected)
-
- result = df.to_html(classes=["sortable", "draggable"])
- self.assertEqual(result, expected)
-
- def test_to_html_no_index_max_rows(self):
- # GH https://github.com/pandas-dev/pandas/issues/14998
- df = DataFrame({"A": [1, 2, 3, 4]})
- result = df.to_html(index=False, max_rows=1)
- expected = dedent("""\
-
-
-
- A |
-
-
-
-
- 1 |
-
-
- """)
- self.assertEqual(result, expected)
-
def test_pprint_pathological_object(self):
"""
if the test fails, the stack will overflow and nose crash,
@@ -3373,541 +1528,6 @@ def test_dict_entries(self):
self.assertTrue("'a': 1" in val)
self.assertTrue("'b': 2" in val)
- def test_to_latex_filename(self):
- with tm.ensure_clean('test.tex') as path:
- self.frame.to_latex(path)
-
- with open(path, 'r') as f:
- self.assertEqual(self.frame.to_latex(), f.read())
-
- # test with utf-8 and encoding option (GH 7061)
- df = DataFrame([[u'au\xdfgangen']])
- with tm.ensure_clean('test.tex') as path:
- df.to_latex(path, encoding='utf-8')
- with codecs.open(path, 'r', encoding='utf-8') as f:
- self.assertEqual(df.to_latex(), f.read())
-
- # test with utf-8 without encoding option
- if compat.PY3: # python3: pandas default encoding is utf-8
- with tm.ensure_clean('test.tex') as path:
- df.to_latex(path)
- with codecs.open(path, 'r', encoding='utf-8') as f:
- self.assertEqual(df.to_latex(), f.read())
- else:
- # python2 default encoding is ascii, so an error should be raised
- with tm.ensure_clean('test.tex') as path:
- self.assertRaises(UnicodeEncodeError, df.to_latex, path)
-
- def test_to_latex(self):
- # it works!
- self.frame.to_latex()
-
- df = DataFrame({'a': [1, 2], 'b': ['b1', 'b2']})
- withindex_result = df.to_latex()
- withindex_expected = r"""\begin{tabular}{lrl}
-\toprule
-{} & a & b \\
-\midrule
-0 & 1 & b1 \\
-1 & 2 & b2 \\
-\bottomrule
-\end{tabular}
-"""
-
- self.assertEqual(withindex_result, withindex_expected)
-
- withoutindex_result = df.to_latex(index=False)
- withoutindex_expected = r"""\begin{tabular}{rl}
-\toprule
- a & b \\
-\midrule
- 1 & b1 \\
- 2 & b2 \\
-\bottomrule
-\end{tabular}
-"""
-
- self.assertEqual(withoutindex_result, withoutindex_expected)
-
- def test_to_latex_format(self):
- # GH Bug #9402
- self.frame.to_latex(column_format='ccc')
-
- df = DataFrame({'a': [1, 2], 'b': ['b1', 'b2']})
- withindex_result = df.to_latex(column_format='ccc')
- withindex_expected = r"""\begin{tabular}{ccc}
-\toprule
-{} & a & b \\
-\midrule
-0 & 1 & b1 \\
-1 & 2 & b2 \\
-\bottomrule
-\end{tabular}
-"""
-
- self.assertEqual(withindex_result, withindex_expected)
-
- def test_to_latex_with_formatters(self):
- df = DataFrame({'int': [1, 2, 3],
- 'float': [1.0, 2.0, 3.0],
- 'object': [(1, 2), True, False],
- 'datetime64': [datetime(2016, 1, 1),
- datetime(2016, 2, 5),
- datetime(2016, 3, 3)]})
-
- formatters = {'int': lambda x: '0x%x' % x,
- 'float': lambda x: '[% 4.1f]' % x,
- 'object': lambda x: '-%s-' % str(x),
- 'datetime64': lambda x: x.strftime('%Y-%m'),
- '__index__': lambda x: 'index: %s' % x}
- result = df.to_latex(formatters=dict(formatters))
-
- expected = r"""\begin{tabular}{llrrl}
-\toprule
-{} & datetime64 & float & int & object \\
-\midrule
-index: 0 & 2016-01 & [ 1.0] & 0x1 & -(1, 2)- \\
-index: 1 & 2016-02 & [ 2.0] & 0x2 & -True- \\
-index: 2 & 2016-03 & [ 3.0] & 0x3 & -False- \\
-\bottomrule
-\end{tabular}
-"""
- self.assertEqual(result, expected)
-
- def test_to_latex_multiindex(self):
- df = DataFrame({('x', 'y'): ['a']})
- result = df.to_latex()
- expected = r"""\begin{tabular}{ll}
-\toprule
-{} & x \\
-{} & y \\
-\midrule
-0 & a \\
-\bottomrule
-\end{tabular}
-"""
-
- self.assertEqual(result, expected)
-
- result = df.T.to_latex()
- expected = r"""\begin{tabular}{lll}
-\toprule
- & & 0 \\
-\midrule
-x & y & a \\
-\bottomrule
-\end{tabular}
-"""
-
- self.assertEqual(result, expected)
-
- df = DataFrame.from_dict({
- ('c1', 0): pd.Series(dict((x, x) for x in range(4))),
- ('c1', 1): pd.Series(dict((x, x + 4) for x in range(4))),
- ('c2', 0): pd.Series(dict((x, x) for x in range(4))),
- ('c2', 1): pd.Series(dict((x, x + 4) for x in range(4))),
- ('c3', 0): pd.Series(dict((x, x) for x in range(4))),
- }).T
- result = df.to_latex()
- expected = r"""\begin{tabular}{llrrrr}
-\toprule
- & & 0 & 1 & 2 & 3 \\
-\midrule
-c1 & 0 & 0 & 1 & 2 & 3 \\
- & 1 & 4 & 5 & 6 & 7 \\
-c2 & 0 & 0 & 1 & 2 & 3 \\
- & 1 & 4 & 5 & 6 & 7 \\
-c3 & 0 & 0 & 1 & 2 & 3 \\
-\bottomrule
-\end{tabular}
-"""
-
- self.assertEqual(result, expected)
-
- # GH 10660
- df = pd.DataFrame({'a': [0, 0, 1, 1],
- 'b': list('abab'),
- 'c': [1, 2, 3, 4]})
- result = df.set_index(['a', 'b']).to_latex()
- expected = r"""\begin{tabular}{llr}
-\toprule
- & & c \\
-a & b & \\
-\midrule
-0 & a & 1 \\
- & b & 2 \\
-1 & a & 3 \\
- & b & 4 \\
-\bottomrule
-\end{tabular}
-"""
-
- self.assertEqual(result, expected)
-
- result = df.groupby('a').describe().to_latex()
- expected = ('\\begin{tabular}{lrrrrrrrr}\n\\toprule\n{} & c & '
- ' & & & & & & '
- '\\\\\n{} & count & mean & std & min & 25\\% & '
- '50\\% & 75\\% & max \\\\\na & & & '
- ' & & & & & \\\\\n\\midrule\n0 '
- '& 2.0 & 1.5 & 0.707107 & 1.0 & 1.25 & 1.5 & 1.75 '
- '& 2.0 \\\\\n1 & 2.0 & 3.5 & 0.707107 & 3.0 & 3.25 '
- '& 3.5 & 3.75 & 4.0 '
- '\\\\\n\\bottomrule\n\\end{tabular}\n')
-
- self.assertEqual(result, expected)
-
- def test_to_latex_escape(self):
- a = 'a'
- b = 'b'
-
- test_dict = {u('co^l1'): {a: "a",
- b: "b"},
- u('co$e^x$'): {a: "a",
- b: "b"}}
-
- unescaped_result = DataFrame(test_dict).to_latex(escape=False)
- escaped_result = DataFrame(test_dict).to_latex(
- ) # default: escape=True
-
- unescaped_expected = r'''\begin{tabular}{lll}
-\toprule
-{} & co$e^x$ & co^l1 \\
-\midrule
-a & a & a \\
-b & b & b \\
-\bottomrule
-\end{tabular}
-'''
-
- escaped_expected = r'''\begin{tabular}{lll}
-\toprule
-{} & co\$e\textasciicircumx\$ & co\textasciicircuml1 \\
-\midrule
-a & a & a \\
-b & b & b \\
-\bottomrule
-\end{tabular}
-'''
-
- self.assertEqual(unescaped_result, unescaped_expected)
- self.assertEqual(escaped_result, escaped_expected)
-
- def test_to_latex_longtable(self):
- self.frame.to_latex(longtable=True)
-
- df = DataFrame({'a': [1, 2], 'b': ['b1', 'b2']})
- withindex_result = df.to_latex(longtable=True)
- withindex_expected = r"""\begin{longtable}{lrl}
-\toprule
-{} & a & b \\
-\midrule
-\endhead
-\midrule
-\multicolumn{3}{r}{{Continued on next page}} \\
-\midrule
-\endfoot
-
-\bottomrule
-\endlastfoot
-0 & 1 & b1 \\
-1 & 2 & b2 \\
-\end{longtable}
-"""
-
- self.assertEqual(withindex_result, withindex_expected)
-
- withoutindex_result = df.to_latex(index=False, longtable=True)
- withoutindex_expected = r"""\begin{longtable}{rl}
-\toprule
- a & b \\
-\midrule
-\endhead
-\midrule
-\multicolumn{3}{r}{{Continued on next page}} \\
-\midrule
-\endfoot
-
-\bottomrule
-\endlastfoot
- 1 & b1 \\
- 2 & b2 \\
-\end{longtable}
-"""
-
- self.assertEqual(withoutindex_result, withoutindex_expected)
-
- def test_to_latex_escape_special_chars(self):
- special_characters = ['&', '%', '$', '#', '_', '{', '}', '~', '^',
- '\\']
- df = DataFrame(data=special_characters)
- observed = df.to_latex()
- expected = r"""\begin{tabular}{ll}
-\toprule
-{} & 0 \\
-\midrule
-0 & \& \\
-1 & \% \\
-2 & \$ \\
-3 & \# \\
-4 & \_ \\
-5 & \{ \\
-6 & \} \\
-7 & \textasciitilde \\
-8 & \textasciicircum \\
-9 & \textbackslash \\
-\bottomrule
-\end{tabular}
-"""
-
- self.assertEqual(observed, expected)
-
- def test_to_latex_no_header(self):
- # GH 7124
- df = DataFrame({'a': [1, 2], 'b': ['b1', 'b2']})
- withindex_result = df.to_latex(header=False)
- withindex_expected = r"""\begin{tabular}{lrl}
-\toprule
-0 & 1 & b1 \\
-1 & 2 & b2 \\
-\bottomrule
-\end{tabular}
-"""
-
- self.assertEqual(withindex_result, withindex_expected)
-
- withoutindex_result = df.to_latex(index=False, header=False)
- withoutindex_expected = r"""\begin{tabular}{rl}
-\toprule
- 1 & b1 \\
- 2 & b2 \\
-\bottomrule
-\end{tabular}
-"""
-
- self.assertEqual(withoutindex_result, withoutindex_expected)
-
- def test_to_latex_decimal(self):
- # GH 12031
- self.frame.to_latex()
- df = DataFrame({'a': [1.0, 2.1], 'b': ['b1', 'b2']})
- withindex_result = df.to_latex(decimal=',')
- print("WHAT THE")
- withindex_expected = r"""\begin{tabular}{lrl}
-\toprule
-{} & a & b \\
-\midrule
-0 & 1,0 & b1 \\
-1 & 2,1 & b2 \\
-\bottomrule
-\end{tabular}
-"""
-
- self.assertEqual(withindex_result, withindex_expected)
-
- def test_to_csv_quotechar(self):
- df = DataFrame({'col': [1, 2]})
- expected = """\
-"","col"
-"0","1"
-"1","2"
-"""
-
- with tm.ensure_clean('test.csv') as path:
- df.to_csv(path, quoting=1) # 1=QUOTE_ALL
- with open(path, 'r') as f:
- self.assertEqual(f.read(), expected)
-
- expected = """\
-$$,$col$
-$0$,$1$
-$1$,$2$
-"""
-
- with tm.ensure_clean('test.csv') as path:
- df.to_csv(path, quoting=1, quotechar="$")
- with open(path, 'r') as f:
- self.assertEqual(f.read(), expected)
-
- with tm.ensure_clean('test.csv') as path:
- with tm.assertRaisesRegexp(TypeError, 'quotechar'):
- df.to_csv(path, quoting=1, quotechar=None)
-
- def test_to_csv_doublequote(self):
- df = DataFrame({'col': ['a"a', '"bb"']})
- expected = '''\
-"","col"
-"0","a""a"
-"1","""bb"""
-'''
-
- with tm.ensure_clean('test.csv') as path:
- df.to_csv(path, quoting=1, doublequote=True) # QUOTE_ALL
- with open(path, 'r') as f:
- self.assertEqual(f.read(), expected)
-
- from _csv import Error
- with tm.ensure_clean('test.csv') as path:
- with tm.assertRaisesRegexp(Error, 'escapechar'):
- df.to_csv(path, doublequote=False) # no escapechar set
-
- def test_to_csv_escapechar(self):
- df = DataFrame({'col': ['a"a', '"bb"']})
- expected = '''\
-"","col"
-"0","a\\"a"
-"1","\\"bb\\""
-'''
-
- with tm.ensure_clean('test.csv') as path: # QUOTE_ALL
- df.to_csv(path, quoting=1, doublequote=False, escapechar='\\')
- with open(path, 'r') as f:
- self.assertEqual(f.read(), expected)
-
- df = DataFrame({'col': ['a,a', ',bb,']})
- expected = """\
-,col
-0,a\\,a
-1,\\,bb\\,
-"""
-
- with tm.ensure_clean('test.csv') as path:
- df.to_csv(path, quoting=3, escapechar='\\') # QUOTE_NONE
- with open(path, 'r') as f:
- self.assertEqual(f.read(), expected)
-
- def test_csv_to_string(self):
- df = DataFrame({'col': [1, 2]})
- expected = ',col\n0,1\n1,2\n'
- self.assertEqual(df.to_csv(), expected)
-
- def test_to_csv_decimal(self):
- # GH 781
- df = DataFrame({'col1': [1], 'col2': ['a'], 'col3': [10.1]})
-
- expected_default = ',col1,col2,col3\n0,1,a,10.1\n'
- self.assertEqual(df.to_csv(), expected_default)
-
- expected_european_excel = ';col1;col2;col3\n0;1;a;10,1\n'
- self.assertEqual(
- df.to_csv(decimal=',', sep=';'), expected_european_excel)
-
- expected_float_format_default = ',col1,col2,col3\n0,1,a,10.10\n'
- self.assertEqual(
- df.to_csv(float_format='%.2f'), expected_float_format_default)
-
- expected_float_format = ';col1;col2;col3\n0;1;a;10,10\n'
- self.assertEqual(
- df.to_csv(decimal=',', sep=';',
- float_format='%.2f'), expected_float_format)
-
- # GH 11553: testing if decimal is taken into account for '0.0'
- df = pd.DataFrame({'a': [0, 1.1], 'b': [2.2, 3.3], 'c': 1})
- expected = 'a,b,c\n0^0,2^2,1\n1^1,3^3,1\n'
- self.assertEqual(df.to_csv(index=False, decimal='^'), expected)
-
- # same but for an index
- self.assertEqual(df.set_index('a').to_csv(decimal='^'), expected)
-
- # same for a multi-index
- self.assertEqual(
- df.set_index(['a', 'b']).to_csv(decimal="^"), expected)
-
- def test_to_csv_float_format(self):
- # testing if float_format is taken into account for the index
- # GH 11553
- df = pd.DataFrame({'a': [0, 1], 'b': [2.2, 3.3], 'c': 1})
- expected = 'a,b,c\n0,2.20,1\n1,3.30,1\n'
- self.assertEqual(
- df.set_index('a').to_csv(float_format='%.2f'), expected)
-
- # same for a multi-index
- self.assertEqual(
- df.set_index(['a', 'b']).to_csv(float_format='%.2f'), expected)
-
- def test_to_csv_na_rep(self):
- # testing if NaN values are correctly represented in the index
- # GH 11553
- df = DataFrame({'a': [0, np.NaN], 'b': [0, 1], 'c': [2, 3]})
- expected = "a,b,c\n0.0,0,2\n_,1,3\n"
- self.assertEqual(df.set_index('a').to_csv(na_rep='_'), expected)
- self.assertEqual(df.set_index(['a', 'b']).to_csv(na_rep='_'), expected)
-
- # now with an index containing only NaNs
- df = DataFrame({'a': np.NaN, 'b': [0, 1], 'c': [2, 3]})
- expected = "a,b,c\n_,0,2\n_,1,3\n"
- self.assertEqual(df.set_index('a').to_csv(na_rep='_'), expected)
- self.assertEqual(df.set_index(['a', 'b']).to_csv(na_rep='_'), expected)
-
- # check if na_rep parameter does not break anything when no NaN
- df = DataFrame({'a': 0, 'b': [0, 1], 'c': [2, 3]})
- expected = "a,b,c\n0,0,2\n0,1,3\n"
- self.assertEqual(df.set_index('a').to_csv(na_rep='_'), expected)
- self.assertEqual(df.set_index(['a', 'b']).to_csv(na_rep='_'), expected)
-
- def test_to_csv_date_format(self):
- # GH 10209
- df_sec = DataFrame({'A': pd.date_range('20130101', periods=5, freq='s')
- })
- df_day = DataFrame({'A': pd.date_range('20130101', periods=5, freq='d')
- })
-
- expected_default_sec = ',A\n0,2013-01-01 00:00:00\n1,2013-01-01 00:00:01\n2,2013-01-01 00:00:02' + \
- '\n3,2013-01-01 00:00:03\n4,2013-01-01 00:00:04\n'
- self.assertEqual(df_sec.to_csv(), expected_default_sec)
-
- expected_ymdhms_day = ',A\n0,2013-01-01 00:00:00\n1,2013-01-02 00:00:00\n2,2013-01-03 00:00:00' + \
- '\n3,2013-01-04 00:00:00\n4,2013-01-05 00:00:00\n'
- self.assertEqual(
- df_day.to_csv(
- date_format='%Y-%m-%d %H:%M:%S'), expected_ymdhms_day)
-
- expected_ymd_sec = ',A\n0,2013-01-01\n1,2013-01-01\n2,2013-01-01\n3,2013-01-01\n4,2013-01-01\n'
- self.assertEqual(
- df_sec.to_csv(date_format='%Y-%m-%d'), expected_ymd_sec)
-
- expected_default_day = ',A\n0,2013-01-01\n1,2013-01-02\n2,2013-01-03\n3,2013-01-04\n4,2013-01-05\n'
- self.assertEqual(df_day.to_csv(), expected_default_day)
- self.assertEqual(
- df_day.to_csv(date_format='%Y-%m-%d'), expected_default_day)
-
- # testing if date_format parameter is taken into account for
- # multi-indexed dataframes (GH 7791)
- df_sec['B'] = 0
- df_sec['C'] = 1
- expected_ymd_sec = 'A,B,C\n2013-01-01,0,1\n'
- df_sec_grouped = df_sec.groupby([pd.Grouper(key='A', freq='1h'), 'B'])
- self.assertEqual(df_sec_grouped.mean().to_csv(date_format='%Y-%m-%d'),
- expected_ymd_sec)
-
- def test_to_csv_multi_index(self):
- # see gh-6618
- df = DataFrame([1], columns=pd.MultiIndex.from_arrays([[1], [2]]))
-
- exp = ",1\n,2\n0,1\n"
- self.assertEqual(df.to_csv(), exp)
-
- exp = "1\n2\n1\n"
- self.assertEqual(df.to_csv(index=False), exp)
-
- df = DataFrame([1], columns=pd.MultiIndex.from_arrays([[1], [2]]),
- index=pd.MultiIndex.from_arrays([[1], [2]]))
-
- exp = ",,1\n,,2\n1,2,1\n"
- self.assertEqual(df.to_csv(), exp)
-
- exp = "1\n2\n1\n"
- self.assertEqual(df.to_csv(index=False), exp)
-
- df = DataFrame(
- [1], columns=pd.MultiIndex.from_arrays([['foo'], ['bar']]))
-
- exp = ",foo\n,bar\n0,1\n"
- self.assertEqual(df.to_csv(), exp)
-
- exp = "foo\nbar\n1\n"
- self.assertEqual(df.to_csv(index=False), exp)
-
def test_period(self):
# GH 12615
df = pd.DataFrame({'A': pd.period_range('2013-01',
@@ -4291,7 +1911,7 @@ def test_max_multi_index_display(self):
['one', 'two', 'one', 'two', 'one', 'two', 'one', 'two']]
tuples = list(zip(*arrays))
index = MultiIndex.from_tuples(tuples, names=['first', 'second'])
- s = Series(randn(8), index=index)
+ s = Series(np.random.randn(8), index=index)
with option_context("display.max_rows", 10):
self.assertEqual(len(str(s).split('\n')), 10)
@@ -4305,7 +1925,7 @@ def test_max_multi_index_display(self):
self.assertEqual(len(str(s).split('\n')), 10)
# index
- s = Series(randn(8), None)
+ s = Series(np.random.randn(8), None)
with option_context("display.max_rows", 10):
self.assertEqual(len(str(s).split('\n')), 9)
@@ -4436,176 +2056,6 @@ def test_to_string_header(self):
self.assertEqual(res, exp)
-class TestEngFormatter(tm.TestCase):
-
- def test_eng_float_formatter(self):
- df = DataFrame({'A': [1.41, 141., 14100, 1410000.]})
-
- fmt.set_eng_float_format()
- result = df.to_string()
- expected = (' A\n'
- '0 1.410E+00\n'
- '1 141.000E+00\n'
- '2 14.100E+03\n'
- '3 1.410E+06')
- self.assertEqual(result, expected)
-
- fmt.set_eng_float_format(use_eng_prefix=True)
- result = df.to_string()
- expected = (' A\n'
- '0 1.410\n'
- '1 141.000\n'
- '2 14.100k\n'
- '3 1.410M')
- self.assertEqual(result, expected)
-
- fmt.set_eng_float_format(accuracy=0)
- result = df.to_string()
- expected = (' A\n'
- '0 1E+00\n'
- '1 141E+00\n'
- '2 14E+03\n'
- '3 1E+06')
- self.assertEqual(result, expected)
-
- self.reset_display_options()
-
- def compare(self, formatter, input, output):
- formatted_input = formatter(input)
- msg = ("formatting of %s results in '%s', expected '%s'" %
- (str(input), formatted_input, output))
- self.assertEqual(formatted_input, output, msg)
-
- def compare_all(self, formatter, in_out):
- """
- Parameters:
- -----------
- formatter: EngFormatter under test
- in_out: list of tuples. Each tuple = (number, expected_formatting)
-
- It is tested if 'formatter(number) == expected_formatting'.
- *number* should be >= 0 because formatter(-number) == fmt is also
- tested. *fmt* is derived from *expected_formatting*
- """
- for input, output in in_out:
- self.compare(formatter, input, output)
- self.compare(formatter, -input, "-" + output[1:])
-
- def test_exponents_with_eng_prefix(self):
- formatter = fmt.EngFormatter(accuracy=3, use_eng_prefix=True)
- f = np.sqrt(2)
- in_out = [(f * 10 ** -24, " 1.414y"), (f * 10 ** -23, " 14.142y"),
- (f * 10 ** -22, " 141.421y"), (f * 10 ** -21, " 1.414z"),
- (f * 10 ** -20, " 14.142z"), (f * 10 ** -19, " 141.421z"),
- (f * 10 ** -18, " 1.414a"), (f * 10 ** -17, " 14.142a"),
- (f * 10 ** -16, " 141.421a"), (f * 10 ** -15, " 1.414f"),
- (f * 10 ** -14, " 14.142f"), (f * 10 ** -13, " 141.421f"),
- (f * 10 ** -12, " 1.414p"), (f * 10 ** -11, " 14.142p"),
- (f * 10 ** -10, " 141.421p"), (f * 10 ** -9, " 1.414n"),
- (f * 10 ** -8, " 14.142n"), (f * 10 ** -7, " 141.421n"),
- (f * 10 ** -6, " 1.414u"), (f * 10 ** -5, " 14.142u"),
- (f * 10 ** -4, " 141.421u"), (f * 10 ** -3, " 1.414m"),
- (f * 10 ** -2, " 14.142m"), (f * 10 ** -1, " 141.421m"),
- (f * 10 ** 0, " 1.414"), (f * 10 ** 1, " 14.142"),
- (f * 10 ** 2, " 141.421"), (f * 10 ** 3, " 1.414k"),
- (f * 10 ** 4, " 14.142k"), (f * 10 ** 5, " 141.421k"),
- (f * 10 ** 6, " 1.414M"), (f * 10 ** 7, " 14.142M"),
- (f * 10 ** 8, " 141.421M"), (f * 10 ** 9, " 1.414G"), (
- f * 10 ** 10, " 14.142G"), (f * 10 ** 11, " 141.421G"),
- (f * 10 ** 12, " 1.414T"), (f * 10 ** 13, " 14.142T"), (
- f * 10 ** 14, " 141.421T"), (f * 10 ** 15, " 1.414P"), (
- f * 10 ** 16, " 14.142P"), (f * 10 ** 17, " 141.421P"), (
- f * 10 ** 18, " 1.414E"), (f * 10 ** 19, " 14.142E"),
- (f * 10 ** 20, " 141.421E"), (f * 10 ** 21, " 1.414Z"), (
- f * 10 ** 22, " 14.142Z"), (f * 10 ** 23, " 141.421Z"), (
- f * 10 ** 24, " 1.414Y"), (f * 10 ** 25, " 14.142Y"), (
- f * 10 ** 26, " 141.421Y")]
- self.compare_all(formatter, in_out)
-
- def test_exponents_without_eng_prefix(self):
- formatter = fmt.EngFormatter(accuracy=4, use_eng_prefix=False)
- f = np.pi
- in_out = [(f * 10 ** -24, " 3.1416E-24"),
- (f * 10 ** -23, " 31.4159E-24"),
- (f * 10 ** -22, " 314.1593E-24"),
- (f * 10 ** -21, " 3.1416E-21"),
- (f * 10 ** -20, " 31.4159E-21"),
- (f * 10 ** -19, " 314.1593E-21"),
- (f * 10 ** -18, " 3.1416E-18"),
- (f * 10 ** -17, " 31.4159E-18"),
- (f * 10 ** -16, " 314.1593E-18"),
- (f * 10 ** -15, " 3.1416E-15"),
- (f * 10 ** -14, " 31.4159E-15"),
- (f * 10 ** -13, " 314.1593E-15"),
- (f * 10 ** -12, " 3.1416E-12"),
- (f * 10 ** -11, " 31.4159E-12"),
- (f * 10 ** -10, " 314.1593E-12"),
- (f * 10 ** -9, " 3.1416E-09"), (f * 10 ** -8, " 31.4159E-09"),
- (f * 10 ** -7, " 314.1593E-09"), (f * 10 ** -6, " 3.1416E-06"),
- (f * 10 ** -5, " 31.4159E-06"), (f * 10 ** -4,
- " 314.1593E-06"),
- (f * 10 ** -3, " 3.1416E-03"), (f * 10 ** -2, " 31.4159E-03"),
- (f * 10 ** -1, " 314.1593E-03"), (f * 10 ** 0, " 3.1416E+00"), (
- f * 10 ** 1, " 31.4159E+00"), (f * 10 ** 2, " 314.1593E+00"),
- (f * 10 ** 3, " 3.1416E+03"), (f * 10 ** 4, " 31.4159E+03"), (
- f * 10 ** 5, " 314.1593E+03"), (f * 10 ** 6, " 3.1416E+06"),
- (f * 10 ** 7, " 31.4159E+06"), (f * 10 ** 8, " 314.1593E+06"), (
- f * 10 ** 9, " 3.1416E+09"), (f * 10 ** 10, " 31.4159E+09"),
- (f * 10 ** 11, " 314.1593E+09"), (f * 10 ** 12, " 3.1416E+12"),
- (f * 10 ** 13, " 31.4159E+12"), (f * 10 ** 14, " 314.1593E+12"),
- (f * 10 ** 15, " 3.1416E+15"), (f * 10 ** 16, " 31.4159E+15"),
- (f * 10 ** 17, " 314.1593E+15"), (f * 10 ** 18, " 3.1416E+18"),
- (f * 10 ** 19, " 31.4159E+18"), (f * 10 ** 20, " 314.1593E+18"),
- (f * 10 ** 21, " 3.1416E+21"), (f * 10 ** 22, " 31.4159E+21"),
- (f * 10 ** 23, " 314.1593E+21"), (f * 10 ** 24, " 3.1416E+24"),
- (f * 10 ** 25, " 31.4159E+24"), (f * 10 ** 26, " 314.1593E+24")]
- self.compare_all(formatter, in_out)
-
- def test_rounding(self):
- formatter = fmt.EngFormatter(accuracy=3, use_eng_prefix=True)
- in_out = [(5.55555, ' 5.556'), (55.5555, ' 55.556'),
- (555.555, ' 555.555'), (5555.55, ' 5.556k'),
- (55555.5, ' 55.556k'), (555555, ' 555.555k')]
- self.compare_all(formatter, in_out)
-
- formatter = fmt.EngFormatter(accuracy=1, use_eng_prefix=True)
- in_out = [(5.55555, ' 5.6'), (55.5555, ' 55.6'), (555.555, ' 555.6'),
- (5555.55, ' 5.6k'), (55555.5, ' 55.6k'), (555555, ' 555.6k')]
- self.compare_all(formatter, in_out)
-
- formatter = fmt.EngFormatter(accuracy=0, use_eng_prefix=True)
- in_out = [(5.55555, ' 6'), (55.5555, ' 56'), (555.555, ' 556'),
- (5555.55, ' 6k'), (55555.5, ' 56k'), (555555, ' 556k')]
- self.compare_all(formatter, in_out)
-
- formatter = fmt.EngFormatter(accuracy=3, use_eng_prefix=True)
- result = formatter(0)
- self.assertEqual(result, u(' 0.000'))
-
- def test_nan(self):
- # Issue #11981
-
- formatter = fmt.EngFormatter(accuracy=1, use_eng_prefix=True)
- result = formatter(np.nan)
- self.assertEqual(result, u('NaN'))
-
- df = pd.DataFrame({'a': [1.5, 10.3, 20.5],
- 'b': [50.3, 60.67, 70.12],
- 'c': [100.2, 101.33, 120.33]})
- pt = df.pivot_table(values='a', index='b', columns='c')
- fmt.set_eng_float_format(accuracy=1)
- result = pt.to_string()
- self.assertTrue('NaN' in result)
- self.reset_display_options()
-
- def test_inf(self):
- # Issue #11981
-
- formatter = fmt.EngFormatter(accuracy=1, use_eng_prefix=True)
- result = formatter(np.inf)
- self.assertEqual(result, u('inf'))
-
-
def _three_digit_exp():
return '%.4g' % 1.7e8 == '1.7e+008'
diff --git a/pandas/tests/formats/test_to_csv.py b/pandas/tests/formats/test_to_csv.py
new file mode 100644
index 0000000000000..51295fd750602
--- /dev/null
+++ b/pandas/tests/formats/test_to_csv.py
@@ -0,0 +1,216 @@
+from pandas import DataFrame
+import numpy as np
+import pandas as pd
+from pandas.util import testing as tm
+
+
+class TestToCSV(tm.TestCase):
+
+ def test_to_csv_quotechar(self):
+ df = DataFrame({'col': [1, 2]})
+ expected = """\
+"","col"
+"0","1"
+"1","2"
+"""
+
+ with tm.ensure_clean('test.csv') as path:
+ df.to_csv(path, quoting=1) # 1=QUOTE_ALL
+ with open(path, 'r') as f:
+ self.assertEqual(f.read(), expected)
+
+ expected = """\
+$$,$col$
+$0$,$1$
+$1$,$2$
+"""
+
+ with tm.ensure_clean('test.csv') as path:
+ df.to_csv(path, quoting=1, quotechar="$")
+ with open(path, 'r') as f:
+ self.assertEqual(f.read(), expected)
+
+ with tm.ensure_clean('test.csv') as path:
+ with tm.assertRaisesRegexp(TypeError, 'quotechar'):
+ df.to_csv(path, quoting=1, quotechar=None)
+
+ def test_to_csv_doublequote(self):
+ df = DataFrame({'col': ['a"a', '"bb"']})
+ expected = '''\
+"","col"
+"0","a""a"
+"1","""bb"""
+'''
+
+ with tm.ensure_clean('test.csv') as path:
+ df.to_csv(path, quoting=1, doublequote=True) # QUOTE_ALL
+ with open(path, 'r') as f:
+ self.assertEqual(f.read(), expected)
+
+ from _csv import Error
+ with tm.ensure_clean('test.csv') as path:
+ with tm.assertRaisesRegexp(Error, 'escapechar'):
+ df.to_csv(path, doublequote=False) # no escapechar set
+
+ def test_to_csv_escapechar(self):
+ df = DataFrame({'col': ['a"a', '"bb"']})
+ expected = '''\
+"","col"
+"0","a\\"a"
+"1","\\"bb\\""
+'''
+
+ with tm.ensure_clean('test.csv') as path: # QUOTE_ALL
+ df.to_csv(path, quoting=1, doublequote=False, escapechar='\\')
+ with open(path, 'r') as f:
+ self.assertEqual(f.read(), expected)
+
+ df = DataFrame({'col': ['a,a', ',bb,']})
+ expected = """\
+,col
+0,a\\,a
+1,\\,bb\\,
+"""
+
+ with tm.ensure_clean('test.csv') as path:
+ df.to_csv(path, quoting=3, escapechar='\\') # QUOTE_NONE
+ with open(path, 'r') as f:
+ self.assertEqual(f.read(), expected)
+
+ def test_csv_to_string(self):
+ df = DataFrame({'col': [1, 2]})
+ expected = ',col\n0,1\n1,2\n'
+ self.assertEqual(df.to_csv(), expected)
+
+ def test_to_csv_decimal(self):
+ # GH 781
+ df = DataFrame({'col1': [1], 'col2': ['a'], 'col3': [10.1]})
+
+ expected_default = ',col1,col2,col3\n0,1,a,10.1\n'
+ self.assertEqual(df.to_csv(), expected_default)
+
+ expected_european_excel = ';col1;col2;col3\n0;1;a;10,1\n'
+ self.assertEqual(
+ df.to_csv(decimal=',', sep=';'), expected_european_excel)
+
+ expected_float_format_default = ',col1,col2,col3\n0,1,a,10.10\n'
+ self.assertEqual(
+ df.to_csv(float_format='%.2f'), expected_float_format_default)
+
+ expected_float_format = ';col1;col2;col3\n0;1;a;10,10\n'
+ self.assertEqual(
+ df.to_csv(decimal=',', sep=';',
+ float_format='%.2f'), expected_float_format)
+
+ # GH 11553: testing if decimal is taken into account for '0.0'
+ df = pd.DataFrame({'a': [0, 1.1], 'b': [2.2, 3.3], 'c': 1})
+ expected = 'a,b,c\n0^0,2^2,1\n1^1,3^3,1\n'
+ self.assertEqual(df.to_csv(index=False, decimal='^'), expected)
+
+ # same but for an index
+ self.assertEqual(df.set_index('a').to_csv(decimal='^'), expected)
+
+ # same for a multi-index
+ self.assertEqual(
+ df.set_index(['a', 'b']).to_csv(decimal="^"), expected)
+
+ def test_to_csv_float_format(self):
+ # testing if float_format is taken into account for the index
+ # GH 11553
+ df = pd.DataFrame({'a': [0, 1], 'b': [2.2, 3.3], 'c': 1})
+ expected = 'a,b,c\n0,2.20,1\n1,3.30,1\n'
+ self.assertEqual(
+ df.set_index('a').to_csv(float_format='%.2f'), expected)
+
+ # same for a multi-index
+ self.assertEqual(
+ df.set_index(['a', 'b']).to_csv(float_format='%.2f'), expected)
+
+ def test_to_csv_na_rep(self):
+ # testing if NaN values are correctly represented in the index
+ # GH 11553
+ df = DataFrame({'a': [0, np.NaN], 'b': [0, 1], 'c': [2, 3]})
+ expected = "a,b,c\n0.0,0,2\n_,1,3\n"
+ self.assertEqual(df.set_index('a').to_csv(na_rep='_'), expected)
+ self.assertEqual(df.set_index(['a', 'b']).to_csv(na_rep='_'), expected)
+
+ # now with an index containing only NaNs
+ df = DataFrame({'a': np.NaN, 'b': [0, 1], 'c': [2, 3]})
+ expected = "a,b,c\n_,0,2\n_,1,3\n"
+ self.assertEqual(df.set_index('a').to_csv(na_rep='_'), expected)
+ self.assertEqual(df.set_index(['a', 'b']).to_csv(na_rep='_'), expected)
+
+ # check if na_rep parameter does not break anything when no NaN
+ df = DataFrame({'a': 0, 'b': [0, 1], 'c': [2, 3]})
+ expected = "a,b,c\n0,0,2\n0,1,3\n"
+ self.assertEqual(df.set_index('a').to_csv(na_rep='_'), expected)
+ self.assertEqual(df.set_index(['a', 'b']).to_csv(na_rep='_'), expected)
+
+ def test_to_csv_date_format(self):
+ # GH 10209
+ df_sec = DataFrame({'A': pd.date_range('20130101', periods=5, freq='s')
+ })
+ df_day = DataFrame({'A': pd.date_range('20130101', periods=5, freq='d')
+ })
+
+ expected_default_sec = (',A\n0,2013-01-01 00:00:00\n1,'
+ '2013-01-01 00:00:01\n2,2013-01-01 00:00:02'
+ '\n3,2013-01-01 00:00:03\n4,'
+ '2013-01-01 00:00:04\n')
+ self.assertEqual(df_sec.to_csv(), expected_default_sec)
+
+ expected_ymdhms_day = (',A\n0,2013-01-01 00:00:00\n1,'
+ '2013-01-02 00:00:00\n2,2013-01-03 00:00:00'
+ '\n3,2013-01-04 00:00:00\n4,'
+ '2013-01-05 00:00:00\n')
+ self.assertEqual(
+ df_day.to_csv(
+ date_format='%Y-%m-%d %H:%M:%S'), expected_ymdhms_day)
+
+ expected_ymd_sec = (',A\n0,2013-01-01\n1,2013-01-01\n2,'
+ '2013-01-01\n3,2013-01-01\n4,2013-01-01\n')
+ self.assertEqual(
+ df_sec.to_csv(date_format='%Y-%m-%d'), expected_ymd_sec)
+
+ expected_default_day = (',A\n0,2013-01-01\n1,2013-01-02\n2,'
+ '2013-01-03\n3,2013-01-04\n4,2013-01-05\n')
+ self.assertEqual(df_day.to_csv(), expected_default_day)
+ self.assertEqual(
+ df_day.to_csv(date_format='%Y-%m-%d'), expected_default_day)
+
+ # testing if date_format parameter is taken into account for
+ # multi-indexed dataframes (GH 7791)
+ df_sec['B'] = 0
+ df_sec['C'] = 1
+ expected_ymd_sec = 'A,B,C\n2013-01-01,0,1\n'
+ df_sec_grouped = df_sec.groupby([pd.Grouper(key='A', freq='1h'), 'B'])
+ self.assertEqual(df_sec_grouped.mean().to_csv(date_format='%Y-%m-%d'),
+ expected_ymd_sec)
+
+ def test_to_csv_multi_index(self):
+ # see gh-6618
+ df = DataFrame([1], columns=pd.MultiIndex.from_arrays([[1], [2]]))
+
+ exp = ",1\n,2\n0,1\n"
+ self.assertEqual(df.to_csv(), exp)
+
+ exp = "1\n2\n1\n"
+ self.assertEqual(df.to_csv(index=False), exp)
+
+ df = DataFrame([1], columns=pd.MultiIndex.from_arrays([[1], [2]]),
+ index=pd.MultiIndex.from_arrays([[1], [2]]))
+
+ exp = ",,1\n,,2\n1,2,1\n"
+ self.assertEqual(df.to_csv(), exp)
+
+ exp = "1\n2\n1\n"
+ self.assertEqual(df.to_csv(index=False), exp)
+
+ df = DataFrame(
+ [1], columns=pd.MultiIndex.from_arrays([['foo'], ['bar']]))
+
+ exp = ",foo\n,bar\n0,1\n"
+ self.assertEqual(df.to_csv(), exp)
+
+ exp = "foo\nbar\n1\n"
+ self.assertEqual(df.to_csv(index=False), exp)
diff --git a/pandas/tests/formats/test_to_html.py b/pandas/tests/formats/test_to_html.py
new file mode 100644
index 0000000000000..771c66e84037c
--- /dev/null
+++ b/pandas/tests/formats/test_to_html.py
@@ -0,0 +1,1861 @@
+# -*- coding: utf-8 -*-
+
+import re
+from textwrap import dedent
+from datetime import datetime
+from distutils.version import LooseVersion
+
+import pytest
+import numpy as np
+import pandas as pd
+from pandas import compat, DataFrame, MultiIndex, option_context, Index
+from pandas.compat import u, lrange, StringIO
+from pandas.util import testing as tm
+import pandas.formats.format as fmt
+
+div_style = ''
+try:
+ import IPython
+ if IPython.__version__ < LooseVersion('3.0.0'):
+ div_style = ' style="max-width:1500px;overflow:auto;"'
+except (ImportError, AttributeError):
+ pass
+
+
+class TestToHTML(tm.TestCase):
+
+ def test_to_html_with_col_space(self):
+ def check_with_width(df, col_space):
+ # check that col_space affects HTML generation
+ # and be very brittle about it.
+ html = df.to_html(col_space=col_space)
+ hdrs = [x for x in html.split(r"\n") if re.search(r"\s]", x)]
+ self.assertTrue(len(hdrs) > 0)
+ for h in hdrs:
+ self.assertTrue("min-width" in h)
+ self.assertTrue(str(col_space) in h)
+
+ df = DataFrame(np.random.random(size=(1, 3)))
+
+ check_with_width(df, 30)
+ check_with_width(df, 50)
+
+ def test_to_html_with_empty_string_label(self):
+ # GH3547, to_html regards empty string labels as repeated labels
+ data = {'c1': ['a', 'b'], 'c2': ['a', ''], 'data': [1, 2]}
+ df = DataFrame(data).set_index(['c1', 'c2'])
+ res = df.to_html()
+ self.assertTrue("rowspan" not in res)
+
+ def test_to_html_unicode(self):
+ df = DataFrame({u('\u03c3'): np.arange(10.)})
+ expected = u'\n \n \n | \n \u03c3 | \n \n \n \n \n 0 | \n 0.0 | \n \n \n 1 | \n 1.0 | \n \n \n 2 | \n 2.0 | \n \n \n 3 | \n 3.0 | \n \n \n 4 | \n 4.0 | \n \n \n 5 | \n 5.0 | \n \n \n 6 | \n 6.0 | \n \n \n 7 | \n 7.0 | \n \n \n 8 | \n 8.0 | \n \n \n 9 | \n 9.0 | \n \n \n ' # noqa
+ self.assertEqual(df.to_html(), expected)
+ df = DataFrame({'A': [u('\u03c3')]})
+ expected = u'\n \n \n | \n A | \n \n \n \n \n 0 | \n \u03c3 | \n \n \n ' # noqa
+ self.assertEqual(df.to_html(), expected)
+
+ def test_to_html_decimal(self):
+ # GH 12031
+ df = DataFrame({'A': [6.0, 3.1, 2.2]})
+ result = df.to_html(decimal=',')
+ expected = ('\n'
+ ' \n'
+ ' \n'
+ ' | \n'
+ ' A | \n'
+ ' \n'
+ ' \n'
+ ' \n'
+ ' \n'
+ ' 0 | \n'
+ ' 6,0 | \n'
+ ' \n'
+ ' \n'
+ ' 1 | \n'
+ ' 3,1 | \n'
+ ' \n'
+ ' \n'
+ ' 2 | \n'
+ ' 2,2 | \n'
+ ' \n'
+ ' \n'
+ ' ')
+ self.assertEqual(result, expected)
+
+ def test_to_html_escaped(self):
+ a = 'str",
+ b: ""},
+ 'co>l2': {a: "",
+ b: ""}}
+ rs = DataFrame(test_dict).to_html()
+ xp = """
+
+
+ |
+ co<l1 |
+ co>l2 |
+
+
+
+
+ str<ing1 & |
+ <type 'str'> |
+ <type 'str'> |
+
+
+ stri>ng2 & |
+ <type 'str'> |
+ <type 'str'> |
+
+
+ """
+
+ self.assertEqual(xp, rs)
+
+ def test_to_html_escape_disabled(self):
+ a = 'strbold",
+ b: "bold"},
+ 'co>l2': {a: "bold",
+ b: "bold"}}
+ rs = DataFrame(test_dict).to_html(escape=False)
+ xp = """
+
+
+ |
+ co
+ co>l2 |
+ |
+
+
+
+ str
+ bold |
+ bold |
+ |
+
+ stri>ng2 & |
+ bold |
+ bold |
+
+
+ """
+
+ self.assertEqual(xp, rs)
+
+ def test_to_html_multiindex_index_false(self):
+ # issue 8452
+ df = DataFrame({
+ 'a': range(2),
+ 'b': range(3, 5),
+ 'c': range(5, 7),
+ 'd': range(3, 5)
+ })
+ df.columns = MultiIndex.from_product([['a', 'b'], ['c', 'd']])
+ result = df.to_html(index=False)
+ expected = """\
+
+
+
+ a |
+ b |
+
+
+ c |
+ d |
+ c |
+ d |
+
+
+
+
+ 0 |
+ 3 |
+ 5 |
+ 3 |
+
+
+ 1 |
+ 4 |
+ 6 |
+ 4 |
+
+
+ """
+
+ self.assertEqual(result, expected)
+
+ df.index = Index(df.index.values, name='idx')
+ result = df.to_html(index=False)
+ self.assertEqual(result, expected)
+
+ def test_to_html_multiindex_sparsify_false_multi_sparse(self):
+ with option_context('display.multi_sparse', False):
+ index = MultiIndex.from_arrays([[0, 0, 1, 1], [0, 1, 0, 1]],
+ names=['foo', None])
+
+ df = DataFrame([[0, 1], [2, 3], [4, 5], [6, 7]], index=index)
+
+ result = df.to_html()
+ expected = """\
+
+
+
+ |
+ |
+ 0 |
+ 1 |
+
+
+ foo |
+ |
+ |
+ |
+
+
+
+
+ 0 |
+ 0 |
+ 0 |
+ 1 |
+
+
+ 0 |
+ 1 |
+ 2 |
+ 3 |
+
+
+ 1 |
+ 0 |
+ 4 |
+ 5 |
+
+
+ 1 |
+ 1 |
+ 6 |
+ 7 |
+
+
+ """
+
+ self.assertEqual(result, expected)
+
+ df = DataFrame([[0, 1], [2, 3], [4, 5], [6, 7]],
+ columns=index[::2], index=index)
+
+ result = df.to_html()
+ expected = """\
+
+
+
+ |
+ foo |
+ 0 |
+ 1 |
+
+
+ |
+ |
+ 0 |
+ 0 |
+
+
+ foo |
+ |
+ |
+ |
+
+
+
+
+ 0 |
+ 0 |
+ 0 |
+ 1 |
+
+
+ 0 |
+ 1 |
+ 2 |
+ 3 |
+
+
+ 1 |
+ 0 |
+ 4 |
+ 5 |
+
+
+ 1 |
+ 1 |
+ 6 |
+ 7 |
+
+
+ """
+
+ self.assertEqual(result, expected)
+
+ def test_to_html_multiindex_sparsify(self):
+ index = MultiIndex.from_arrays([[0, 0, 1, 1], [0, 1, 0, 1]],
+ names=['foo', None])
+
+ df = DataFrame([[0, 1], [2, 3], [4, 5], [6, 7]], index=index)
+
+ result = df.to_html()
+ expected = """
+
+
+ |
+ |
+ 0 |
+ 1 |
+
+
+ foo |
+ |
+ |
+ |
+
+
+
+
+ 0 |
+ 0 |
+ 0 |
+ 1 |
+
+
+ 1 |
+ 2 |
+ 3 |
+
+
+ 1 |
+ 0 |
+ 4 |
+ 5 |
+
+
+ 1 |
+ 6 |
+ 7 |
+
+
+ """
+
+ self.assertEqual(result, expected)
+
+ df = DataFrame([[0, 1], [2, 3], [4, 5], [6, 7]], columns=index[::2],
+ index=index)
+
+ result = df.to_html()
+ expected = """\
+
+
+
+ |
+ foo |
+ 0 |
+ 1 |
+
+
+ |
+ |
+ 0 |
+ 0 |
+
+
+ foo |
+ |
+ |
+ |
+
+
+
+
+ 0 |
+ 0 |
+ 0 |
+ 1 |
+
+
+ 1 |
+ 2 |
+ 3 |
+
+
+ 1 |
+ 0 |
+ 4 |
+ 5 |
+
+
+ 1 |
+ 6 |
+ 7 |
+
+
+ """
+
+ self.assertEqual(result, expected)
+
+ def test_to_html_multiindex_odd_even_truncate(self):
+ # GH 14882 - Issue on truncation with odd length DataFrame
+ mi = MultiIndex.from_product([[100, 200, 300],
+ [10, 20, 30],
+ [1, 2, 3, 4, 5, 6, 7]],
+ names=['a', 'b', 'c'])
+ df = DataFrame({'n': range(len(mi))}, index=mi)
+ result = df.to_html(max_rows=60)
+ expected = """\
+
+
+
+ |
+ |
+ |
+ n |
+
+
+ a |
+ b |
+ c |
+ |
+
+
+
+
+ 100 |
+ 10 |
+ 1 |
+ 0 |
+
+
+ 2 |
+ 1 |
+
+
+ 3 |
+ 2 |
+
+
+ 4 |
+ 3 |
+
+
+ 5 |
+ 4 |
+
+
+ 6 |
+ 5 |
+
+
+ 7 |
+ 6 |
+
+
+ 20 |
+ 1 |
+ 7 |
+
+
+ 2 |
+ 8 |
+
+
+ 3 |
+ 9 |
+
+
+ 4 |
+ 10 |
+
+
+ 5 |
+ 11 |
+
+
+ 6 |
+ 12 |
+
+
+ 7 |
+ 13 |
+
+
+ 30 |
+ 1 |
+ 14 |
+
+
+ 2 |
+ 15 |
+
+
+ 3 |
+ 16 |
+
+
+ 4 |
+ 17 |
+
+
+ 5 |
+ 18 |
+
+
+ 6 |
+ 19 |
+
+
+ 7 |
+ 20 |
+
+
+ 200 |
+ 10 |
+ 1 |
+ 21 |
+
+
+ 2 |
+ 22 |
+
+
+ 3 |
+ 23 |
+
+
+ 4 |
+ 24 |
+
+
+ 5 |
+ 25 |
+
+
+ 6 |
+ 26 |
+
+
+ 7 |
+ 27 |
+
+
+ 20 |
+ 1 |
+ 28 |
+
+
+ 2 |
+ 29 |
+
+
+ ... |
+ ... |
+
+
+ 6 |
+ 33 |
+
+
+ 7 |
+ 34 |
+
+
+ 30 |
+ 1 |
+ 35 |
+
+
+ 2 |
+ 36 |
+
+
+ 3 |
+ 37 |
+
+
+ 4 |
+ 38 |
+
+
+ 5 |
+ 39 |
+
+
+ 6 |
+ 40 |
+
+
+ 7 |
+ 41 |
+
+
+ 300 |
+ 10 |
+ 1 |
+ 42 |
+
+
+ 2 |
+ 43 |
+
+
+ 3 |
+ 44 |
+
+
+ 4 |
+ 45 |
+
+
+ 5 |
+ 46 |
+
+
+ 6 |
+ 47 |
+
+
+ 7 |
+ 48 |
+
+
+ 20 |
+ 1 |
+ 49 |
+
+
+ 2 |
+ 50 |
+
+
+ 3 |
+ 51 |
+
+
+ 4 |
+ 52 |
+
+
+ 5 |
+ 53 |
+
+
+ 6 |
+ 54 |
+
+
+ 7 |
+ 55 |
+
+
+ 30 |
+ 1 |
+ 56 |
+
+
+ 2 |
+ 57 |
+
+
+ 3 |
+ 58 |
+
+
+ 4 |
+ 59 |
+
+
+ 5 |
+ 60 |
+
+
+ 6 |
+ 61 |
+
+
+ 7 |
+ 62 |
+
+
+ """
+ self.assertEqual(result, expected)
+
+ # Test that ... appears in a middle level
+ result = df.to_html(max_rows=56)
+ expected = """\
+
+
+
+ |
+ |
+ |
+ n |
+
+
+ a |
+ b |
+ c |
+ |
+
+
+
+
+ 100 |
+ 10 |
+ 1 |
+ 0 |
+
+
+ 2 |
+ 1 |
+
+
+ 3 |
+ 2 |
+
+
+ 4 |
+ 3 |
+
+
+ 5 |
+ 4 |
+
+
+ 6 |
+ 5 |
+
+
+ 7 |
+ 6 |
+
+
+ 20 |
+ 1 |
+ 7 |
+
+
+ 2 |
+ 8 |
+
+
+ 3 |
+ 9 |
+
+
+ 4 |
+ 10 |
+
+
+ 5 |
+ 11 |
+
+
+ 6 |
+ 12 |
+
+
+ 7 |
+ 13 |
+
+
+ 30 |
+ 1 |
+ 14 |
+
+
+ 2 |
+ 15 |
+
+
+ 3 |
+ 16 |
+
+
+ 4 |
+ 17 |
+
+
+ 5 |
+ 18 |
+
+
+ 6 |
+ 19 |
+
+
+ 7 |
+ 20 |
+
+
+ 200 |
+ 10 |
+ 1 |
+ 21 |
+
+
+ 2 |
+ 22 |
+
+
+ 3 |
+ 23 |
+
+
+ 4 |
+ 24 |
+
+
+ 5 |
+ 25 |
+
+
+ 6 |
+ 26 |
+
+
+ 7 |
+ 27 |
+
+
+ ... |
+ ... |
+ ... |
+
+
+ 30 |
+ 1 |
+ 35 |
+
+
+ 2 |
+ 36 |
+
+
+ 3 |
+ 37 |
+
+
+ 4 |
+ 38 |
+
+
+ 5 |
+ 39 |
+
+
+ 6 |
+ 40 |
+
+
+ 7 |
+ 41 |
+
+
+ 300 |
+ 10 |
+ 1 |
+ 42 |
+
+
+ 2 |
+ 43 |
+
+
+ 3 |
+ 44 |
+
+
+ 4 |
+ 45 |
+
+
+ 5 |
+ 46 |
+
+
+ 6 |
+ 47 |
+
+
+ 7 |
+ 48 |
+
+
+ 20 |
+ 1 |
+ 49 |
+
+
+ 2 |
+ 50 |
+
+
+ 3 |
+ 51 |
+
+
+ 4 |
+ 52 |
+
+
+ 5 |
+ 53 |
+
+
+ 6 |
+ 54 |
+
+
+ 7 |
+ 55 |
+
+
+ 30 |
+ 1 |
+ 56 |
+
+
+ 2 |
+ 57 |
+
+
+ 3 |
+ 58 |
+
+
+ 4 |
+ 59 |
+
+
+ 5 |
+ 60 |
+
+
+ 6 |
+ 61 |
+
+
+ 7 |
+ 62 |
+
+
+ """
+ self.assertEqual(result, expected)
+
+ def test_to_html_index_formatter(self):
+ df = DataFrame([[0, 1], [2, 3], [4, 5], [6, 7]], columns=['foo', None],
+ index=lrange(4))
+
+ f = lambda x: 'abcd' [x]
+ result = df.to_html(formatters={'__index__': f})
+ expected = """\
+
+
+
+ |
+ foo |
+ None |
+
+
+
+
+ a |
+ 0 |
+ 1 |
+
+
+ b |
+ 2 |
+ 3 |
+
+
+ c |
+ 4 |
+ 5 |
+
+
+ d |
+ 6 |
+ 7 |
+
+
+ """
+
+ self.assertEqual(result, expected)
+
+ def test_to_html_datetime64_monthformatter(self):
+ months = [datetime(2016, 1, 1), datetime(2016, 2, 2)]
+ x = DataFrame({'months': months})
+
+ def format_func(x):
+ return x.strftime('%Y-%m')
+ result = x.to_html(formatters={'months': format_func})
+ expected = """\
+
+
+
+ |
+ months |
+
+
+
+
+ 0 |
+ 2016-01 |
+
+
+ 1 |
+ 2016-02 |
+
+
+ """
+ self.assertEqual(result, expected)
+
+ def test_to_html_datetime64_hourformatter(self):
+
+ x = DataFrame({'hod': pd.to_datetime(['10:10:10.100', '12:12:12.120'],
+ format='%H:%M:%S.%f')})
+
+ def format_func(x):
+ return x.strftime('%H:%M')
+ result = x.to_html(formatters={'hod': format_func})
+ expected = """\
+
+
+
+ |
+ hod |
+
+
+
+
+ 0 |
+ 10:10 |
+
+
+ 1 |
+ 12:12 |
+
+
+ """
+ self.assertEqual(result, expected)
+
+ def test_to_html_regression_GH6098(self):
+ df = DataFrame({
+ u('clé1'): [u('a'), u('a'), u('b'), u('b'), u('a')],
+ u('clé2'): [u('1er'), u('2ème'), u('1er'), u('2ème'), u('1er')],
+ 'données1': np.random.randn(5),
+ 'données2': np.random.randn(5)})
+
+ # it works
+ df.pivot_table(index=[u('clé1')], columns=[u('clé2')])._repr_html_()
+
+ def test_to_html_truncate(self):
+ pytest.skip("unreliable on travis")
+ index = pd.DatetimeIndex(start='20010101', freq='D', periods=20)
+ df = DataFrame(index=index, columns=range(20))
+ fmt.set_option('display.max_rows', 8)
+ fmt.set_option('display.max_columns', 4)
+ result = df._repr_html_()
+ expected = '''\
+
+
+
+
+ |
+ 0 |
+ 1 |
+ ... |
+ 18 |
+ 19 |
+
+
+
+
+ 2001-01-01 |
+ NaN |
+ NaN |
+ ... |
+ NaN |
+ NaN |
+
+
+ 2001-01-02 |
+ NaN |
+ NaN |
+ ... |
+ NaN |
+ NaN |
+
+
+ 2001-01-03 |
+ NaN |
+ NaN |
+ ... |
+ NaN |
+ NaN |
+
+
+ 2001-01-04 |
+ NaN |
+ NaN |
+ ... |
+ NaN |
+ NaN |
+
+
+ ... |
+ ... |
+ ... |
+ ... |
+ ... |
+ ... |
+
+
+ 2001-01-17 |
+ NaN |
+ NaN |
+ ... |
+ NaN |
+ NaN |
+
+
+ 2001-01-18 |
+ NaN |
+ NaN |
+ ... |
+ NaN |
+ NaN |
+
+
+ 2001-01-19 |
+ NaN |
+ NaN |
+ ... |
+ NaN |
+ NaN |
+
+
+ 2001-01-20 |
+ NaN |
+ NaN |
+ ... |
+ NaN |
+ NaN |
+
+
+
+ 20 rows × 20 columns
+ '''.format(div_style)
+ if compat.PY2:
+ expected = expected.decode('utf-8')
+ self.assertEqual(result, expected)
+
+ def test_to_html_truncate_multi_index(self):
+ pytest.skip("unreliable on travis")
+ arrays = [['bar', 'bar', 'baz', 'baz', 'foo', 'foo', 'qux', 'qux'],
+ ['one', 'two', 'one', 'two', 'one', 'two', 'one', 'two']]
+ df = DataFrame(index=arrays, columns=arrays)
+ fmt.set_option('display.max_rows', 7)
+ fmt.set_option('display.max_columns', 7)
+ result = df._repr_html_()
+ expected = '''\
+
+
+
+
+ |
+ |
+ bar |
+ baz |
+ ... |
+ foo |
+ qux |
+
+
+ |
+ |
+ one |
+ two |
+ one |
+ ... |
+ two |
+ one |
+ two |
+
+
+
+
+ bar |
+ one |
+ NaN |
+ NaN |
+ NaN |
+ ... |
+ NaN |
+ NaN |
+ NaN |
+
+
+ two |
+ NaN |
+ NaN |
+ NaN |
+ ... |
+ NaN |
+ NaN |
+ NaN |
+
+
+ baz |
+ one |
+ NaN |
+ NaN |
+ NaN |
+ ... |
+ NaN |
+ NaN |
+ NaN |
+
+
+ ... |
+ ... |
+ ... |
+ ... |
+ ... |
+ ... |
+ ... |
+ ... |
+ ... |
+
+
+ foo |
+ two |
+ NaN |
+ NaN |
+ NaN |
+ ... |
+ NaN |
+ NaN |
+ NaN |
+
+
+ qux |
+ one |
+ NaN |
+ NaN |
+ NaN |
+ ... |
+ NaN |
+ NaN |
+ NaN |
+
+
+ two |
+ NaN |
+ NaN |
+ NaN |
+ ... |
+ NaN |
+ NaN |
+ NaN |
+
+
+
+ 8 rows × 8 columns
+ '''.format(div_style)
+ if compat.PY2:
+ expected = expected.decode('utf-8')
+ self.assertEqual(result, expected)
+
+ def test_to_html_truncate_multi_index_sparse_off(self):
+ pytest.skip("unreliable on travis")
+ arrays = [['bar', 'bar', 'baz', 'baz', 'foo', 'foo', 'qux', 'qux'],
+ ['one', 'two', 'one', 'two', 'one', 'two', 'one', 'two']]
+ df = DataFrame(index=arrays, columns=arrays)
+ fmt.set_option('display.max_rows', 7)
+ fmt.set_option('display.max_columns', 7)
+ fmt.set_option('display.multi_sparse', False)
+ result = df._repr_html_()
+ expected = '''\
+
+
+
+
+ |
+ |
+ bar |
+ bar |
+ baz |
+ ... |
+ foo |
+ qux |
+ qux |
+
+
+ |
+ |
+ one |
+ two |
+ one |
+ ... |
+ two |
+ one |
+ two |
+
+
+
+
+ bar |
+ one |
+ NaN |
+ NaN |
+ NaN |
+ ... |
+ NaN |
+ NaN |
+ NaN |
+
+
+ bar |
+ two |
+ NaN |
+ NaN |
+ NaN |
+ ... |
+ NaN |
+ NaN |
+ NaN |
+
+
+ baz |
+ one |
+ NaN |
+ NaN |
+ NaN |
+ ... |
+ NaN |
+ NaN |
+ NaN |
+
+
+ foo |
+ two |
+ NaN |
+ NaN |
+ NaN |
+ ... |
+ NaN |
+ NaN |
+ NaN |
+
+
+ qux |
+ one |
+ NaN |
+ NaN |
+ NaN |
+ ... |
+ NaN |
+ NaN |
+ NaN |
+
+
+ qux |
+ two |
+ NaN |
+ NaN |
+ NaN |
+ ... |
+ NaN |
+ NaN |
+ NaN |
+
+
+
+ 8 rows × 8 columns
+ '''.format(div_style)
+ if compat.PY2:
+ expected = expected.decode('utf-8')
+ self.assertEqual(result, expected)
+
+ def test_to_html_border(self):
+ df = DataFrame({'A': [1, 2]})
+ result = df.to_html()
+ assert 'border="1"' in result
+
+ def test_to_html_border_option(self):
+ df = DataFrame({'A': [1, 2]})
+ with pd.option_context('html.border', 0):
+ result = df.to_html()
+ self.assertTrue('border="0"' in result)
+ self.assertTrue('border="0"' in df._repr_html_())
+
+ def test_to_html_border_zero(self):
+ df = DataFrame({'A': [1, 2]})
+ result = df.to_html(border=0)
+ self.assertTrue('border="0"' in result)
+
+ def test_to_html(self):
+ # big mixed
+ biggie = DataFrame({'A': np.random.randn(200),
+ 'B': tm.makeStringIndex(200)},
+ index=lrange(200))
+
+ biggie.loc[:20, 'A'] = np.nan
+ biggie.loc[:20, 'B'] = np.nan
+ s = biggie.to_html()
+
+ buf = StringIO()
+ retval = biggie.to_html(buf=buf)
+ self.assertIsNone(retval)
+ self.assertEqual(buf.getvalue(), s)
+
+ tm.assertIsInstance(s, compat.string_types)
+
+ biggie.to_html(columns=['B', 'A'], col_space=17)
+ biggie.to_html(columns=['B', 'A'],
+ formatters={'A': lambda x: '%.1f' % x})
+
+ biggie.to_html(columns=['B', 'A'], float_format=str)
+ biggie.to_html(columns=['B', 'A'], col_space=12, float_format=str)
+
+ frame = DataFrame(index=np.arange(200))
+ frame.to_html()
+
+ def test_to_html_filename(self):
+ biggie = DataFrame({'A': np.random.randn(200),
+ 'B': tm.makeStringIndex(200)},
+ index=lrange(200))
+
+ biggie.loc[:20, 'A'] = np.nan
+ biggie.loc[:20, 'B'] = np.nan
+ with tm.ensure_clean('test.html') as path:
+ biggie.to_html(path)
+ with open(path, 'r') as f:
+ s = biggie.to_html()
+ s2 = f.read()
+ self.assertEqual(s, s2)
+
+ frame = DataFrame(index=np.arange(200))
+ with tm.ensure_clean('test.html') as path:
+ frame.to_html(path)
+ with open(path, 'r') as f:
+ self.assertEqual(frame.to_html(), f.read())
+
+ def test_to_html_with_no_bold(self):
+ x = DataFrame({'x': np.random.randn(5)})
+ ashtml = x.to_html(bold_rows=False)
+ self.assertFalse('")])
+
+ def test_to_html_columns_arg(self):
+ frame = DataFrame(tm.getSeriesData())
+ result = frame.to_html(columns=['A'])
+ self.assertNotIn('B | ', result)
+
+ def test_to_html_multiindex(self):
+ columns = MultiIndex.from_tuples(list(zip(np.arange(2).repeat(2),
+ np.mod(lrange(4), 2))),
+ names=['CL0', 'CL1'])
+ df = DataFrame([list('abcd'), list('efgh')], columns=columns)
+ result = df.to_html(justify='left')
+ expected = ('\n'
+ ' \n'
+ ' \n'
+ ' CL0 | \n'
+ ' 0 | \n'
+ ' 1 | \n'
+ ' \n'
+ ' \n'
+ ' CL1 | \n'
+ ' 0 | \n'
+ ' 1 | \n'
+ ' 0 | \n'
+ ' 1 | \n'
+ ' \n'
+ ' \n'
+ ' \n'
+ ' \n'
+ ' 0 | \n'
+ ' a | \n'
+ ' b | \n'
+ ' c | \n'
+ ' d | \n'
+ ' \n'
+ ' \n'
+ ' 1 | \n'
+ ' e | \n'
+ ' f | \n'
+ ' g | \n'
+ ' h | \n'
+ ' \n'
+ ' \n'
+ ' ')
+
+ self.assertEqual(result, expected)
+
+ columns = MultiIndex.from_tuples(list(zip(
+ range(4), np.mod(
+ lrange(4), 2))))
+ df = DataFrame([list('abcd'), list('efgh')], columns=columns)
+
+ result = df.to_html(justify='right')
+ expected = ('\n'
+ ' \n'
+ ' \n'
+ ' | \n'
+ ' 0 | \n'
+ ' 1 | \n'
+ ' 2 | \n'
+ ' 3 | \n'
+ ' \n'
+ ' \n'
+ ' | \n'
+ ' 0 | \n'
+ ' 1 | \n'
+ ' 0 | \n'
+ ' 1 | \n'
+ ' \n'
+ ' \n'
+ ' \n'
+ ' \n'
+ ' 0 | \n'
+ ' a | \n'
+ ' b | \n'
+ ' c | \n'
+ ' d | \n'
+ ' \n'
+ ' \n'
+ ' 1 | \n'
+ ' e | \n'
+ ' f | \n'
+ ' g | \n'
+ ' h | \n'
+ ' \n'
+ ' \n'
+ ' ')
+
+ self.assertEqual(result, expected)
+
+ def test_to_html_justify(self):
+ df = DataFrame({'A': [6, 30000, 2],
+ 'B': [1, 2, 70000],
+ 'C': [223442, 0, 1]},
+ columns=['A', 'B', 'C'])
+ result = df.to_html(justify='left')
+ expected = ('\n'
+ ' \n'
+ ' \n'
+ ' | \n'
+ ' A | \n'
+ ' B | \n'
+ ' C | \n'
+ ' \n'
+ ' \n'
+ ' \n'
+ ' \n'
+ ' 0 | \n'
+ ' 6 | \n'
+ ' 1 | \n'
+ ' 223442 | \n'
+ ' \n'
+ ' \n'
+ ' 1 | \n'
+ ' 30000 | \n'
+ ' 2 | \n'
+ ' 0 | \n'
+ ' \n'
+ ' \n'
+ ' 2 | \n'
+ ' 2 | \n'
+ ' 70000 | \n'
+ ' 1 | \n'
+ ' \n'
+ ' \n'
+ ' ')
+ self.assertEqual(result, expected)
+
+ result = df.to_html(justify='right')
+ expected = ('\n'
+ ' \n'
+ ' \n'
+ ' | \n'
+ ' A | \n'
+ ' B | \n'
+ ' C | \n'
+ ' \n'
+ ' \n'
+ ' \n'
+ ' \n'
+ ' 0 | \n'
+ ' 6 | \n'
+ ' 1 | \n'
+ ' 223442 | \n'
+ ' \n'
+ ' \n'
+ ' 1 | \n'
+ ' 30000 | \n'
+ ' 2 | \n'
+ ' 0 | \n'
+ ' \n'
+ ' \n'
+ ' 2 | \n'
+ ' 2 | \n'
+ ' 70000 | \n'
+ ' 1 | \n'
+ ' \n'
+ ' \n'
+ ' ')
+ self.assertEqual(result, expected)
+
+ def test_to_html_index(self):
+ index = ['foo', 'bar', 'baz']
+ df = DataFrame({'A': [1, 2, 3],
+ 'B': [1.2, 3.4, 5.6],
+ 'C': ['one', 'two', np.nan]},
+ columns=['A', 'B', 'C'],
+ index=index)
+ expected_with_index = ('\n'
+ ' \n'
+ ' \n'
+ ' | \n'
+ ' A | \n'
+ ' B | \n'
+ ' C | \n'
+ ' \n'
+ ' \n'
+ ' \n'
+ ' \n'
+ ' foo | \n'
+ ' 1 | \n'
+ ' 1.2 | \n'
+ ' one | \n'
+ ' \n'
+ ' \n'
+ ' bar | \n'
+ ' 2 | \n'
+ ' 3.4 | \n'
+ ' two | \n'
+ ' \n'
+ ' \n'
+ ' baz | \n'
+ ' 3 | \n'
+ ' 5.6 | \n'
+ ' NaN | \n'
+ ' \n'
+ ' \n'
+ ' ')
+ self.assertEqual(df.to_html(), expected_with_index)
+
+ expected_without_index = ('\n'
+ ' \n'
+ ' \n'
+ ' A | \n'
+ ' B | \n'
+ ' C | \n'
+ ' \n'
+ ' \n'
+ ' \n'
+ ' \n'
+ ' 1 | \n'
+ ' 1.2 | \n'
+ ' one | \n'
+ ' \n'
+ ' \n'
+ ' 2 | \n'
+ ' 3.4 | \n'
+ ' two | \n'
+ ' \n'
+ ' \n'
+ ' 3 | \n'
+ ' 5.6 | \n'
+ ' NaN | \n'
+ ' \n'
+ ' \n'
+ ' ')
+ result = df.to_html(index=False)
+ for i in index:
+ self.assertNotIn(i, result)
+ self.assertEqual(result, expected_without_index)
+ df.index = Index(['foo', 'bar', 'baz'], name='idx')
+ expected_with_index = ('\n'
+ ' \n'
+ ' \n'
+ ' | \n'
+ ' A | \n'
+ ' B | \n'
+ ' C | \n'
+ ' \n'
+ ' \n'
+ ' idx | \n'
+ ' | \n'
+ ' | \n'
+ ' | \n'
+ ' \n'
+ ' \n'
+ ' \n'
+ ' \n'
+ ' foo | \n'
+ ' 1 | \n'
+ ' 1.2 | \n'
+ ' one | \n'
+ ' \n'
+ ' \n'
+ ' bar | \n'
+ ' 2 | \n'
+ ' 3.4 | \n'
+ ' two | \n'
+ ' \n'
+ ' \n'
+ ' baz | \n'
+ ' 3 | \n'
+ ' 5.6 | \n'
+ ' NaN | \n'
+ ' \n'
+ ' \n'
+ ' ')
+ self.assertEqual(df.to_html(), expected_with_index)
+ self.assertEqual(df.to_html(index=False), expected_without_index)
+
+ tuples = [('foo', 'car'), ('foo', 'bike'), ('bar', 'car')]
+ df.index = MultiIndex.from_tuples(tuples)
+
+ expected_with_index = ('\n'
+ ' \n'
+ ' \n'
+ ' | \n'
+ ' | \n'
+ ' A | \n'
+ ' B | \n'
+ ' C | \n'
+ ' \n'
+ ' \n'
+ ' \n'
+ ' \n'
+ ' foo | \n'
+ ' car | \n'
+ ' 1 | \n'
+ ' 1.2 | \n'
+ ' one | \n'
+ ' \n'
+ ' \n'
+ ' bike | \n'
+ ' 2 | \n'
+ ' 3.4 | \n'
+ ' two | \n'
+ ' \n'
+ ' \n'
+ ' bar | \n'
+ ' car | \n'
+ ' 3 | \n'
+ ' 5.6 | \n'
+ ' NaN | \n'
+ ' \n'
+ ' \n'
+ ' ')
+ self.assertEqual(df.to_html(), expected_with_index)
+
+ result = df.to_html(index=False)
+ for i in ['foo', 'bar', 'car', 'bike']:
+ self.assertNotIn(i, result)
+ # must be the same result as normal index
+ self.assertEqual(result, expected_without_index)
+
+ df.index = MultiIndex.from_tuples(tuples, names=['idx1', 'idx2'])
+ expected_with_index = ('\n'
+ ' \n'
+ ' \n'
+ ' | \n'
+ ' | \n'
+ ' A | \n'
+ ' B | \n'
+ ' C | \n'
+ ' \n'
+ ' \n'
+ ' idx1 | \n'
+ ' idx2 | \n'
+ ' | \n'
+ ' | \n'
+ ' | \n'
+ ' \n'
+ ' \n'
+ ' \n'
+ ' \n'
+ ' foo | \n'
+ ' car | \n'
+ ' 1 | \n'
+ ' 1.2 | \n'
+ ' one | \n'
+ ' \n'
+ ' \n'
+ ' bike | \n'
+ ' 2 | \n'
+ ' 3.4 | \n'
+ ' two | \n'
+ ' \n'
+ ' \n'
+ ' bar | \n'
+ ' car | \n'
+ ' 3 | \n'
+ ' 5.6 | \n'
+ ' NaN | \n'
+ ' \n'
+ ' \n'
+ ' ')
+ self.assertEqual(df.to_html(), expected_with_index)
+ self.assertEqual(df.to_html(index=False), expected_without_index)
+
+ def test_to_html_with_classes(self):
+ df = DataFrame()
+ result = df.to_html(classes="sortable draggable")
+ expected = dedent("""
+
+
+
+ """).strip()
+ self.assertEqual(result, expected)
+
+ result = df.to_html(classes=["sortable", "draggable"])
+ self.assertEqual(result, expected)
+
+ def test_to_html_no_index_max_rows(self):
+ # GH https://github.com/pandas-dev/pandas/issues/14998
+ df = DataFrame({"A": [1, 2, 3, 4]})
+ result = df.to_html(index=False, max_rows=1)
+ expected = dedent("""\
+
+
+
+ A |
+
+
+
+
+ 1 |
+
+
+ """)
+ self.assertEqual(result, expected)
diff --git a/pandas/tests/formats/test_to_latex.py b/pandas/tests/formats/test_to_latex.py
new file mode 100644
index 0000000000000..89e18e1cec06e
--- /dev/null
+++ b/pandas/tests/formats/test_to_latex.py
@@ -0,0 +1,351 @@
+from datetime import datetime
+
+import pytest
+
+import pandas as pd
+from pandas import DataFrame, compat
+from pandas.util import testing as tm
+from pandas.compat import u
+import codecs
+
+
+@pytest.fixture
+def frame():
+ return DataFrame(tm.getSeriesData())
+
+
+class TestToLatex(object):
+
+ def test_to_latex_filename(self, frame):
+ with tm.ensure_clean('test.tex') as path:
+ frame.to_latex(path)
+
+ with open(path, 'r') as f:
+ assert frame.to_latex() == f.read()
+
+ # test with utf-8 and encoding option (GH 7061)
+ df = DataFrame([[u'au\xdfgangen']])
+ with tm.ensure_clean('test.tex') as path:
+ df.to_latex(path, encoding='utf-8')
+ with codecs.open(path, 'r', encoding='utf-8') as f:
+ assert df.to_latex() == f.read()
+
+ # test with utf-8 without encoding option
+ if compat.PY3: # python3: pandas default encoding is utf-8
+ with tm.ensure_clean('test.tex') as path:
+ df.to_latex(path)
+ with codecs.open(path, 'r', encoding='utf-8') as f:
+ assert df.to_latex() == f.read()
+ else:
+ # python2 default encoding is ascii, so an error should be raised
+ with tm.ensure_clean('test.tex') as path:
+ with pytest.raises(UnicodeEncodeError):
+ df.to_latex(path)
+
+ def test_to_latex(self, frame):
+ # it works!
+ frame.to_latex()
+
+ df = DataFrame({'a': [1, 2], 'b': ['b1', 'b2']})
+ withindex_result = df.to_latex()
+ withindex_expected = r"""\begin{tabular}{lrl}
+\toprule
+{} & a & b \\
+\midrule
+0 & 1 & b1 \\
+1 & 2 & b2 \\
+\bottomrule
+\end{tabular}
+"""
+
+ assert withindex_result == withindex_expected
+
+ withoutindex_result = df.to_latex(index=False)
+ withoutindex_expected = r"""\begin{tabular}{rl}
+\toprule
+ a & b \\
+\midrule
+ 1 & b1 \\
+ 2 & b2 \\
+\bottomrule
+\end{tabular}
+"""
+
+ assert withoutindex_result == withoutindex_expected
+
+ def test_to_latex_format(self, frame):
+ # GH Bug #9402
+ frame.to_latex(column_format='ccc')
+
+ df = DataFrame({'a': [1, 2], 'b': ['b1', 'b2']})
+ withindex_result = df.to_latex(column_format='ccc')
+ withindex_expected = r"""\begin{tabular}{ccc}
+\toprule
+{} & a & b \\
+\midrule
+0 & 1 & b1 \\
+1 & 2 & b2 \\
+\bottomrule
+\end{tabular}
+"""
+
+ assert withindex_result == withindex_expected
+
+ def test_to_latex_with_formatters(self):
+ df = DataFrame({'int': [1, 2, 3],
+ 'float': [1.0, 2.0, 3.0],
+ 'object': [(1, 2), True, False],
+ 'datetime64': [datetime(2016, 1, 1),
+ datetime(2016, 2, 5),
+ datetime(2016, 3, 3)]})
+
+ formatters = {'int': lambda x: '0x%x' % x,
+ 'float': lambda x: '[% 4.1f]' % x,
+ 'object': lambda x: '-%s-' % str(x),
+ 'datetime64': lambda x: x.strftime('%Y-%m'),
+ '__index__': lambda x: 'index: %s' % x}
+ result = df.to_latex(formatters=dict(formatters))
+
+ expected = r"""\begin{tabular}{llrrl}
+\toprule
+{} & datetime64 & float & int & object \\
+\midrule
+index: 0 & 2016-01 & [ 1.0] & 0x1 & -(1, 2)- \\
+index: 1 & 2016-02 & [ 2.0] & 0x2 & -True- \\
+index: 2 & 2016-03 & [ 3.0] & 0x3 & -False- \\
+\bottomrule
+\end{tabular}
+"""
+ assert result == expected
+
+ def test_to_latex_multiindex(self):
+ df = DataFrame({('x', 'y'): ['a']})
+ result = df.to_latex()
+ expected = r"""\begin{tabular}{ll}
+\toprule
+{} & x \\
+{} & y \\
+\midrule
+0 & a \\
+\bottomrule
+\end{tabular}
+"""
+
+ assert result == expected
+
+ result = df.T.to_latex()
+ expected = r"""\begin{tabular}{lll}
+\toprule
+ & & 0 \\
+\midrule
+x & y & a \\
+\bottomrule
+\end{tabular}
+"""
+
+ assert result == expected
+
+ df = DataFrame.from_dict({
+ ('c1', 0): pd.Series(dict((x, x) for x in range(4))),
+ ('c1', 1): pd.Series(dict((x, x + 4) for x in range(4))),
+ ('c2', 0): pd.Series(dict((x, x) for x in range(4))),
+ ('c2', 1): pd.Series(dict((x, x + 4) for x in range(4))),
+ ('c3', 0): pd.Series(dict((x, x) for x in range(4))),
+ }).T
+ result = df.to_latex()
+ expected = r"""\begin{tabular}{llrrrr}
+\toprule
+ & & 0 & 1 & 2 & 3 \\
+\midrule
+c1 & 0 & 0 & 1 & 2 & 3 \\
+ & 1 & 4 & 5 & 6 & 7 \\
+c2 & 0 & 0 & 1 & 2 & 3 \\
+ & 1 & 4 & 5 & 6 & 7 \\
+c3 & 0 & 0 & 1 & 2 & 3 \\
+\bottomrule
+\end{tabular}
+"""
+
+ assert result == expected
+
+ # GH 10660
+ df = pd.DataFrame({'a': [0, 0, 1, 1],
+ 'b': list('abab'),
+ 'c': [1, 2, 3, 4]})
+ result = df.set_index(['a', 'b']).to_latex()
+ expected = r"""\begin{tabular}{llr}
+\toprule
+ & & c \\
+a & b & \\
+\midrule
+0 & a & 1 \\
+ & b & 2 \\
+1 & a & 3 \\
+ & b & 4 \\
+\bottomrule
+\end{tabular}
+"""
+
+ assert result == expected
+
+ result = df.groupby('a').describe().to_latex()
+ expected = ('\\begin{tabular}{lrrrrrrrr}\n\\toprule\n{} & c & '
+ ' & & & & & & '
+ '\\\\\n{} & count & mean & std & min & 25\\% & '
+ '50\\% & 75\\% & max \\\\\na & & & '
+ ' & & & & & \\\\\n\\midrule\n0 '
+ '& 2.0 & 1.5 & 0.707107 & 1.0 & 1.25 & 1.5 & 1.75 '
+ '& 2.0 \\\\\n1 & 2.0 & 3.5 & 0.707107 & 3.0 & 3.25 '
+ '& 3.5 & 3.75 & 4.0 '
+ '\\\\\n\\bottomrule\n\\end{tabular}\n')
+
+ assert result == expected
+
+ def test_to_latex_escape(self):
+ a = 'a'
+ b = 'b'
+
+ test_dict = {u('co^l1'): {a: "a",
+ b: "b"},
+ u('co$e^x$'): {a: "a",
+ b: "b"}}
+
+ unescaped_result = DataFrame(test_dict).to_latex(escape=False)
+ escaped_result = DataFrame(test_dict).to_latex(
+ ) # default: escape=True
+
+ unescaped_expected = r'''\begin{tabular}{lll}
+\toprule
+{} & co$e^x$ & co^l1 \\
+\midrule
+a & a & a \\
+b & b & b \\
+\bottomrule
+\end{tabular}
+'''
+
+ escaped_expected = r'''\begin{tabular}{lll}
+\toprule
+{} & co\$e\textasciicircumx\$ & co\textasciicircuml1 \\
+\midrule
+a & a & a \\
+b & b & b \\
+\bottomrule
+\end{tabular}
+'''
+
+ assert unescaped_result == unescaped_expected
+ assert escaped_result == escaped_expected
+
+ def test_to_latex_longtable(self, frame):
+ frame.to_latex(longtable=True)
+
+ df = DataFrame({'a': [1, 2], 'b': ['b1', 'b2']})
+ withindex_result = df.to_latex(longtable=True)
+ withindex_expected = r"""\begin{longtable}{lrl}
+\toprule
+{} & a & b \\
+\midrule
+\endhead
+\midrule
+\multicolumn{3}{r}{{Continued on next page}} \\
+\midrule
+\endfoot
+
+\bottomrule
+\endlastfoot
+0 & 1 & b1 \\
+1 & 2 & b2 \\
+\end{longtable}
+"""
+
+ assert withindex_result == withindex_expected
+
+ withoutindex_result = df.to_latex(index=False, longtable=True)
+ withoutindex_expected = r"""\begin{longtable}{rl}
+\toprule
+ a & b \\
+\midrule
+\endhead
+\midrule
+\multicolumn{3}{r}{{Continued on next page}} \\
+\midrule
+\endfoot
+
+\bottomrule
+\endlastfoot
+ 1 & b1 \\
+ 2 & b2 \\
+\end{longtable}
+"""
+
+ assert withoutindex_result == withoutindex_expected
+
+ def test_to_latex_escape_special_chars(self):
+ special_characters = ['&', '%', '$', '#', '_', '{', '}', '~', '^',
+ '\\']
+ df = DataFrame(data=special_characters)
+ observed = df.to_latex()
+ expected = r"""\begin{tabular}{ll}
+\toprule
+{} & 0 \\
+\midrule
+0 & \& \\
+1 & \% \\
+2 & \$ \\
+3 & \# \\
+4 & \_ \\
+5 & \{ \\
+6 & \} \\
+7 & \textasciitilde \\
+8 & \textasciicircum \\
+9 & \textbackslash \\
+\bottomrule
+\end{tabular}
+"""
+
+ assert observed == expected
+
+ def test_to_latex_no_header(self):
+ # GH 7124
+ df = DataFrame({'a': [1, 2], 'b': ['b1', 'b2']})
+ withindex_result = df.to_latex(header=False)
+ withindex_expected = r"""\begin{tabular}{lrl}
+\toprule
+0 & 1 & b1 \\
+1 & 2 & b2 \\
+\bottomrule
+\end{tabular}
+"""
+
+ assert withindex_result == withindex_expected
+
+ withoutindex_result = df.to_latex(index=False, header=False)
+ withoutindex_expected = r"""\begin{tabular}{rl}
+\toprule
+ 1 & b1 \\
+ 2 & b2 \\
+\bottomrule
+\end{tabular}
+"""
+
+ assert withoutindex_result == withoutindex_expected
+
+ def test_to_latex_decimal(self, frame):
+ # GH 12031
+ frame.to_latex()
+
+ df = DataFrame({'a': [1.0, 2.1], 'b': ['b1', 'b2']})
+ withindex_result = df.to_latex(decimal=',')
+
+ withindex_expected = r"""\begin{tabular}{lrl}
+\toprule
+{} & a & b \\
+\midrule
+0 & 1,0 & b1 \\
+1 & 2,1 & b2 \\
+\bottomrule
+\end{tabular}
+"""
+
+ assert withindex_result == withindex_expected
| |