From 0b57ab81c99afd801cba21f95eeb7608909191fb Mon Sep 17 00:00:00 2001 From: Mike Ronayne Date: Thu, 29 Apr 2021 13:07:03 -0700 Subject: [PATCH 1/4] Fixed truncation issue. Added test. Not confirmed passing. --- pandas/io/formats/string.py | 11 +++-- pandas/tests/io/formats/test_to_string.py | 57 +++++++++++++++-------- 2 files changed, 45 insertions(+), 23 deletions(-) diff --git a/pandas/io/formats/string.py b/pandas/io/formats/string.py index de53646b5f95f..20fc84a4df303 100644 --- a/pandas/io/formats/string.py +++ b/pandas/io/formats/string.py @@ -74,11 +74,14 @@ def _insert_dot_separators(self, strcols: List[List[str]]) -> List[List[str]]: return strcols + @property + def _adjusted_tr_col_num(self) -> int: + return self.fmt.tr_col_num + 1 if self.fmt.index else self.fmt.tr_col_num + def _insert_dot_separator_horizontal( self, strcols: List[List[str]], index_length: int ) -> List[List[str]]: - tr_col_num = self.fmt.tr_col_num + 1 if self.fmt.index else self.fmt.tr_col_num - strcols.insert(tr_col_num, [" ..."] * index_length) + strcols.insert(self._adjusted_tr_col_num, [" ..."] * index_length) return strcols def _insert_dot_separator_vertical( @@ -90,7 +93,7 @@ def _insert_dot_separator_vertical( cwidth = self.adj.len(col[row_num]) if self.fmt.is_truncated_horizontally: - is_dot_col = ix == self.fmt.tr_col_num + 1 + is_dot_col = ix == self._adjusted_tr_col_num else: is_dot_col = False @@ -99,7 +102,7 @@ def _insert_dot_separator_vertical( else: dots = ".." - if ix == 0: + if ix == 0 and self.fmt.index: dot_mode = "left" elif is_dot_col: cwidth = 4 diff --git a/pandas/tests/io/formats/test_to_string.py b/pandas/tests/io/formats/test_to_string.py index f9b3cac3527ef..42b1cb4a5a9f5 100644 --- a/pandas/tests/io/formats/test_to_string.py +++ b/pandas/tests/io/formats/test_to_string.py @@ -107,37 +107,56 @@ def test_format_remove_leading_space_dataframe(input_array, expected): @pytest.mark.parametrize( - "max_cols, expected", + "max_cols, max_rows, expected", [ ( 10, - [ - " 0 1 2 3 4 ... 6 7 8 9 10", - " 0 0 0 0 0 ... 0 0 0 0 0", - " 0 0 0 0 0 ... 0 0 0 0 0", - ], + None, + " 0 1 2 3 4 ... 6 7 8 9 10\n" + " 0 0 0 0 0 ... 0 0 0 0 0\n" + " 0 0 0 0 0 ... 0 0 0 0 0\n" + " 0 0 0 0 0 ... 0 0 0 0 0\n" + " 0 0 0 0 0 ... 0 0 0 0 0", + ), + ( + None, + 2, + " 0 1 2 3 4 6 7 8 9 10 11\n" + " 0 0 0 0 0 0 0 0 0 0 0\n" + " .. .. .. .. .. .. .. .. .. .. ..\n" + " 0 0 0 0 0 0 0 0 0 0 0", + ), + ( + 10, + 2, + " 0 1 2 3 4 ... 6 7 8 9 10\n" + " 0 0 0 0 0 ... 0 0 0 0 0\n" + " .. .. .. .. .. ... .. .. .. .. ..\n" + " 0 0 0 0 0 ... 0 0 0 0 0", ), ( 9, - [ - " 0 1 2 3 ... 7 8 9 10", - " 0 0 0 0 ... 0 0 0 0", - " 0 0 0 0 ... 0 0 0 0", - ], + 2, + " 0 1 2 3 ... 7 8 9 10\n" + " 0 0 0 0 ... 0 0 0 0\n" + " .. .. .. .. ... .. .. .. ..\n" + " 0 0 0 0 ... 0 0 0 0", ), ( 1, - [ - " 0 ...", - " 0 ...", - " 0 ...", - ], + 1, + " 0 ...\n" + " 0 ...\n" + ".. ...", ), ], ) -def test_truncation_col_placement_no_index(max_cols, expected): - df = DataFrame([[0] * 11] * 2) - assert df.to_string(index=False, max_cols=max_cols).split("\n") == expected +def test_truncation_no_index(max_cols, max_rows, expected): + df = DataFrame([[0] * 11] * 4) + assert ( + df.to_string(index=False, max_cols=max_cols, max_rows=max_rows) + == expected + ) def test_to_string_unicode_columns(float_frame): From ec11e7df87b169c4239b069e547cd6533d3a7438 Mon Sep 17 00:00:00 2001 From: Mike Ronayne Date: Fri, 30 Apr 2021 08:34:51 -0700 Subject: [PATCH 2/4] Updated failing tests and style issues --- pandas/tests/io/formats/test_to_string.py | 23 +++++++++++------------ 1 file changed, 11 insertions(+), 12 deletions(-) diff --git a/pandas/tests/io/formats/test_to_string.py b/pandas/tests/io/formats/test_to_string.py index 42b1cb4a5a9f5..ed7b2683da03c 100644 --- a/pandas/tests/io/formats/test_to_string.py +++ b/pandas/tests/io/formats/test_to_string.py @@ -121,10 +121,10 @@ def test_format_remove_leading_space_dataframe(input_array, expected): ( None, 2, - " 0 1 2 3 4 6 7 8 9 10 11\n" - " 0 0 0 0 0 0 0 0 0 0 0\n" - " .. .. .. .. .. .. .. .. .. .. ..\n" - " 0 0 0 0 0 0 0 0 0 0 0", + " 0 1 2 3 4 5 6 7 8 9 10 11\n" + " 0 0 0 0 0 0 0 0 0 0 0 0\n" + " .. .. .. .. .. .. .. .. .. .. .. ..\n" + " 0 0 0 0 0 0 0 0 0 0 0 0", ), ( 10, @@ -145,18 +145,13 @@ def test_format_remove_leading_space_dataframe(input_array, expected): ( 1, 1, - " 0 ...\n" - " 0 ...\n" - ".. ...", + " 0 ...\n 0 ...\n.. ...", ), ], ) def test_truncation_no_index(max_cols, max_rows, expected): df = DataFrame([[0] * 11] * 4) - assert ( - df.to_string(index=False, max_cols=max_cols, max_rows=max_rows) - == expected - ) + assert df.to_string(index=False, max_cols=max_cols, max_rows=max_rows) == expected def test_to_string_unicode_columns(float_frame): @@ -239,7 +234,11 @@ def format_func(x): def test_to_string_with_datetime64_hourformatter(): x = DataFrame( - {"hod": to_datetime(["10:10:10.100", "12:12:12.120"], format="%H:%M:%S.%f")} + { + "hod": to_datetime( + ["10:10:10.100", "12:12:12.120"], format="%H:%M:%S.%f" + ) + } ) def format_func(x): From d7a2f011d313f1e1d6bec523c468d63125a434b1 Mon Sep 17 00:00:00 2001 From: Mike Ronayne Date: Fri, 30 Apr 2021 09:19:48 -0700 Subject: [PATCH 3/4] Addressed failing tests --- pandas/tests/io/formats/test_to_string.py | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/pandas/tests/io/formats/test_to_string.py b/pandas/tests/io/formats/test_to_string.py index ed7b2683da03c..65a438ad6108b 100644 --- a/pandas/tests/io/formats/test_to_string.py +++ b/pandas/tests/io/formats/test_to_string.py @@ -121,10 +121,10 @@ def test_format_remove_leading_space_dataframe(input_array, expected): ( None, 2, - " 0 1 2 3 4 5 6 7 8 9 10 11\n" - " 0 0 0 0 0 0 0 0 0 0 0 0\n" - " .. .. .. .. .. .. .. .. .. .. .. ..\n" - " 0 0 0 0 0 0 0 0 0 0 0 0", + " 0 1 2 3 4 5 6 7 8 9 10\n" + " 0 0 0 0 0 0 0 0 0 0 0\n" + " .. .. .. .. .. .. .. .. .. .. ..\n" + " 0 0 0 0 0 0 0 0 0 0 0", ), ( 10, @@ -234,11 +234,7 @@ def format_func(x): def test_to_string_with_datetime64_hourformatter(): x = DataFrame( - { - "hod": to_datetime( - ["10:10:10.100", "12:12:12.120"], format="%H:%M:%S.%f" - ) - } + {"hod": to_datetime(["10:10:10.100", "12:12:12.120"], format="%H:%M:%S.%f")} ) def format_func(x): From 4958e1a0d3e8f134fea4a87866a31d91e236ee20 Mon Sep 17 00:00:00 2001 From: Mike Ronayne Date: Mon, 10 May 2021 10:43:33 -0700 Subject: [PATCH 4/4] Updated whatsnew --- doc/source/whatsnew/v1.3.0.rst | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/doc/source/whatsnew/v1.3.0.rst b/doc/source/whatsnew/v1.3.0.rst index 74710ca48308c..6099ab4a9c365 100644 --- a/doc/source/whatsnew/v1.3.0.rst +++ b/doc/source/whatsnew/v1.3.0.rst @@ -796,7 +796,8 @@ I/O - Bug in :func:`read_sas` raising ``ValueError`` when ``datetimes`` were null (:issue:`39725`) - Bug in :func:`read_excel` dropping empty values from single-column spreadsheets (:issue:`39808`) - Bug in :func:`read_excel` raising ``AttributeError`` with ``MultiIndex`` header followed by two empty rows and no index, and bug affecting :func:`read_excel`, :func:`read_csv`, :func:`read_table`, :func:`read_fwf`, and :func:`read_clipboard` where one blank row after a ``MultiIndex`` header with no index would be dropped (:issue:`40442`) -- Bug in :meth:`DataFrame.to_string` misplacing the truncation column when ``index=False`` (:issue:`40907`) +- Bug in :meth:`DataFrame.to_string` misplacing the truncation column when ``index=False`` (:issue:`40904`) +- Bug in :meth:`DataFrame.to_string` adding an extra dot and misaligning the truncation row when ``index=False`` (:issue:`40904`) - Bug in :func:`read_orc` always raising ``AttributeError`` (:issue:`40918`) - Bug in the conversion from pyarrow to pandas (e.g. for reading Parquet) with nullable dtypes and a pyarrow array whose data buffer size is not a multiple of dtype size (:issue:`40896`)