diff --git a/doc/source/whatsnew/v0.18.0.txt b/doc/source/whatsnew/v0.18.0.txt
index ffba681565f48..5acda44c63161 100644
--- a/doc/source/whatsnew/v0.18.0.txt
+++ b/doc/source/whatsnew/v0.18.0.txt
@@ -185,6 +185,48 @@ In addition, ``.round()``, ``.floor()`` and ``.ceil()`` will be available thru t
s
s.dt.round('D')
+
+Formatting of integer in FloatIndex
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+Integers in ``FloatIndex``, e.g. 1., are now formatted with a decimal point
+and a ``0`` digit, e.g. ``1.0`` (:issue:`11713`)
+
+This change affects the display in jupyter, but also the output of IO methods
+like ``.to_csv`` or ``.to_html``
+
+Previous Behavior:
+
+.. code-block:: python
+
+ In [2]: s = Series([1,2,3], index=np.arange(3.))
+
+ In [3]: s
+ Out[3]:
+ 0 1
+ 1 2
+ 2 3
+ dtype: int64
+
+ In [4]: s.index
+ Out[4]: Float64Index([0.0, 1.0, 2.0], dtype='float64')
+
+ In [5]: print(s.to_csv(path=None))
+ 0,1
+ 1,2
+ 2,3
+
+
+New Behavior:
+
+.. ipython:: python
+
+ s = Series([1,2,3], index=np.arange(3.))
+ s
+ s.index
+ print(s.to_csv(path=None))
+
+
.. _whatsnew_0180.enhancements.other:
Other enhancements
diff --git a/pandas/core/format.py b/pandas/core/format.py
index 10b67d6229234..d7f3a669de9f4 100644
--- a/pandas/core/format.py
+++ b/pandas/core/format.py
@@ -2115,7 +2115,9 @@ def _format_strings(self):
abs_vals = np.abs(self.values)
# this is pretty arbitrary for now
- has_large_values = (abs_vals > 1e8).any()
+ # large values: more that 8 characters including decimal symbol
+ # and first digit, hence > 1e6
+ has_large_values = (abs_vals > 1e6).any()
has_small_values = ((abs_vals < 10**(-self.digits)) &
(abs_vals > 0)).any()
@@ -2367,7 +2369,7 @@ def just(x):
def _trim_zeros(str_floats, na_rep='NaN'):
"""
- Trims zeros and decimal points.
+ Trims zeros, leaving just one before the decimal points if need be.
"""
trimmed = str_floats
@@ -2379,8 +2381,8 @@ def _cond(values):
while _cond(trimmed):
trimmed = [x[:-1] if x != na_rep else x for x in trimmed]
- # trim decimal points
- return [x[:-1] if x.endswith('.') and x != na_rep else x for x in trimmed]
+ # leave one 0 after the decimal points if need be.
+ return [x + "0" if x.endswith('.') and x != na_rep else x for x in trimmed]
def single_column_table(column, align=None, style=None):
diff --git a/pandas/tests/test_format.py b/pandas/tests/test_format.py
index b7691033dfc83..2ad25ad738649 100644
--- a/pandas/tests/test_format.py
+++ b/pandas/tests/test_format.py
@@ -204,7 +204,7 @@ def test_repr_chop_threshold(self):
self.assertEqual(repr(df), ' 0 1\n0 0.0 0.5\n1 0.5 0.0')
with option_context("display.chop_threshold", 0.6):
- self.assertEqual(repr(df), ' 0 1\n0 0 0\n1 0 0')
+ self.assertEqual(repr(df), ' 0 1\n0 0.0 0.0\n1 0.0 0.0')
with option_context("display.chop_threshold", None):
self.assertEqual(repr(df), ' 0 1\n0 0.1 0.5\n1 0.5 -0.1')
@@ -753,7 +753,7 @@ def test_to_html_with_empty_string_label(self):
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 | \n
\n \n 1 | \n 1 | \n
\n \n 2 | \n 2 | \n
\n \n 3 | \n 3 | \n
\n \n 4 | \n 4 | \n
\n \n 5 | \n 5 | \n
\n \n 6 | \n 6 | \n
\n \n 7 | \n 7 | \n
\n \n 8 | \n 8 | \n
\n \n 9 | \n 9 | \n
\n \n
'
+ 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
'
@@ -1916,12 +1916,12 @@ def test_to_string_format_na(self):
'B': [np.nan, 'foo', 'foooo', 'fooooo', 'bar']})
result = df.to_string()
- expected = (' A B\n'
- '0 NaN NaN\n'
- '1 -1 foo\n'
- '2 -2 foooo\n'
- '3 3 fooooo\n'
- '4 4 bar')
+ expected = (' A B\n'
+ '0 NaN NaN\n'
+ '1 -1.0 foo\n'
+ '2 -2.0 foooo\n'
+ '3 3.0 fooooo\n'
+ '4 4.0 bar')
self.assertEqual(result, expected)
def test_to_string_line_width(self):
@@ -3760,8 +3760,8 @@ def test_misc(self):
def test_format(self):
obj = fmt.FloatArrayFormatter(np.array([12, 0], dtype=np.float64))
result = obj.get_result()
- self.assertEqual(result[0], " 12")
- self.assertEqual(result[1], " 0")
+ self.assertEqual(result[0], " 12.0")
+ self.assertEqual(result[1], " 0.0")
def test_output_significant_digits(self):
# Issue #9764
@@ -3793,15 +3793,15 @@ def test_output_significant_digits(self):
def test_too_long(self):
# GH 10451
with pd.option_context('display.precision', 4):
- # need both a number > 1e8 and something that normally formats to
+ # need both a number > 1e6 and something that normally formats to
# having length > display.precision + 6
df = pd.DataFrame(dict(x=[12345.6789]))
self.assertEqual(str(df), ' x\n0 12345.6789')
- df = pd.DataFrame(dict(x=[2e8]))
- self.assertEqual(str(df), ' x\n0 200000000')
- df = pd.DataFrame(dict(x=[12345.6789, 2e8]))
+ df = pd.DataFrame(dict(x=[2e6]))
+ self.assertEqual(str(df), ' x\n0 2000000.0')
+ df = pd.DataFrame(dict(x=[12345.6789, 2e6]))
self.assertEqual(
- str(df), ' x\n0 1.2346e+04\n1 2.0000e+08')
+ str(df), ' x\n0 1.2346e+04\n1 2.0000e+06')
class TestRepr_timedelta64(tm.TestCase):