From 27b42a57f375b7d6c98262fad3e4afb2c7e1cdaa Mon Sep 17 00:00:00 2001 From: JustinZhengBC Date: Wed, 6 Feb 2019 16:25:46 -0800 Subject: [PATCH 1/4] BUG-25061 fix printing indices with NaNs --- doc/source/whatsnew/v0.24.2.rst | 2 +- pandas/io/formats/format.py | 5 +++++ pandas/tests/series/test_repr.py | 7 +++++++ 3 files changed, 13 insertions(+), 1 deletion(-) diff --git a/doc/source/whatsnew/v0.24.2.rst b/doc/source/whatsnew/v0.24.2.rst index 6a9a316da1ec6..f3ef116c643e5 100644 --- a/doc/source/whatsnew/v0.24.2.rst +++ b/doc/source/whatsnew/v0.24.2.rst @@ -52,7 +52,7 @@ Bug Fixes **I/O** - Bug in reading a HDF5 table-format ``DataFrame`` created in Python 2, in Python 3 (:issue:`24925`) -- +- Bug where float indexes could have misaligned values when printing (:issue:`25061`) - **Categorical** diff --git a/pandas/io/formats/format.py b/pandas/io/formats/format.py index 62fa04e784072..d2141d0f61153 100644 --- a/pandas/io/formats/format.py +++ b/pandas/io/formats/format.py @@ -1060,6 +1060,11 @@ def get_result_as_array(self): def format_values_with(float_format): formatter = self._value_formatter(float_format, threshold) + # default formatter leaves a space to the left when formatting + # floats, must be consistent for left-justifying NaNs (GH #25061) + if self.justify == 'left': + self.na_rep = ' ' + self.na_rep + # separate the wheat from the chaff values = self.values mask = isna(values) diff --git a/pandas/tests/series/test_repr.py b/pandas/tests/series/test_repr.py index b4e7708e2456e..bc88a5b245ba0 100644 --- a/pandas/tests/series/test_repr.py +++ b/pandas/tests/series/test_repr.py @@ -198,6 +198,13 @@ def test_latex_repr(self): assert s._repr_latex_() is None + def test_categorical_index_repr_in_frame_with_nan(self): + i = Index([1, np.nan]) + s = Series([1, 2], index=i) + exp = """1.0 1\nNaN 2\ndtype: int64""" + + assert repr(s) == exp + class TestCategoricalRepr(object): From 0ba733c4495896ce2b11fb211f7e7413deaec5fc Mon Sep 17 00:00:00 2001 From: JustinZhengBC Date: Wed, 6 Feb 2019 18:18:57 -0800 Subject: [PATCH 2/4] BUG-25061 reference issue in test --- pandas/tests/series/test_repr.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/pandas/tests/series/test_repr.py b/pandas/tests/series/test_repr.py index bc88a5b245ba0..795cc136ccfe7 100644 --- a/pandas/tests/series/test_repr.py +++ b/pandas/tests/series/test_repr.py @@ -198,7 +198,8 @@ def test_latex_repr(self): assert s._repr_latex_() is None - def test_categorical_index_repr_in_frame_with_nan(self): + # GH 25061 + def test_index_repr_in_frame_with_nan(self): i = Index([1, np.nan]) s = Series([1, 2], index=i) exp = """1.0 1\nNaN 2\ndtype: int64""" From c9ed96c402834136549cc29a37725560b2319431 Mon Sep 17 00:00:00 2001 From: gfyoung Date: Wed, 6 Feb 2019 21:13:25 -0800 Subject: [PATCH 3/4] Put test reference comment beneath function def --- pandas/tests/series/test_repr.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pandas/tests/series/test_repr.py b/pandas/tests/series/test_repr.py index 795cc136ccfe7..842207f2a572f 100644 --- a/pandas/tests/series/test_repr.py +++ b/pandas/tests/series/test_repr.py @@ -198,8 +198,8 @@ def test_latex_repr(self): assert s._repr_latex_() is None - # GH 25061 def test_index_repr_in_frame_with_nan(self): + # see gh-25061 i = Index([1, np.nan]) s = Series([1, 2], index=i) exp = """1.0 1\nNaN 2\ndtype: int64""" From a34dd96f0faf17dae7fd88818c10955ac6332b29 Mon Sep 17 00:00:00 2001 From: JustinZhengBC Date: Thu, 7 Feb 2019 19:10:10 -0800 Subject: [PATCH 4/4] BUG-25061 use local na_rep variable --- pandas/io/formats/format.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/pandas/io/formats/format.py b/pandas/io/formats/format.py index d2141d0f61153..f68ef2cc39006 100644 --- a/pandas/io/formats/format.py +++ b/pandas/io/formats/format.py @@ -1063,7 +1063,9 @@ def format_values_with(float_format): # default formatter leaves a space to the left when formatting # floats, must be consistent for left-justifying NaNs (GH #25061) if self.justify == 'left': - self.na_rep = ' ' + self.na_rep + na_rep = ' ' + self.na_rep + else: + na_rep = self.na_rep # separate the wheat from the chaff values = self.values @@ -1071,13 +1073,13 @@ def format_values_with(float_format): if hasattr(values, 'to_dense'): # sparse numpy ndarray values = values.to_dense() values = np.array(values, dtype='object') - values[mask] = self.na_rep + values[mask] = na_rep imask = (~mask).ravel() values.flat[imask] = np.array([formatter(val) for val in values.ravel()[imask]]) if self.fixed_width: - return _trim_zeros(values, self.na_rep) + return _trim_zeros(values, na_rep) return values