From 23f27a219563494fbe27c2b66e922e9d91de0210 Mon Sep 17 00:00:00 2001 From: Roy van Santen Date: Tue, 8 Oct 2019 22:29:02 +0200 Subject: [PATCH 01/15] Show line numbers when calling info on Dataframe --- pandas/core/frame.py | 8 ++++---- pandas/tests/frame/test_repr_info.py | 22 +++++++++++++++++++--- 2 files changed, 23 insertions(+), 7 deletions(-) diff --git a/pandas/core/frame.py b/pandas/core/frame.py index 1a19910a0957c..27212b82cc512 100644 --- a/pandas/core/frame.py +++ b/pandas/core/frame.py @@ -2343,9 +2343,9 @@ def info( RangeIndex: 5 entries, 0 to 4 Data columns (total 3 columns): - int_col 5 non-null int64 - text_col 5 non-null object - float_col 5 non-null float64 + 0. int_col 5 non-null int64 + 1. text_col 5 non-null object + 2. float_col 5 non-null float64 dtypes: float64(1), int64(1), object(1) memory usage: 248.0+ bytes @@ -2455,7 +2455,7 @@ def _verbose_repr(): count = counts.iloc[i] lines.append( - _put_str(col, space) + tmpl.format(count=count, dtype=dtype) + str(i) + ". " + _put_str(col, space) + tmpl.format(count=count, dtype=dtype) ) def _non_verbose_repr(): diff --git a/pandas/tests/frame/test_repr_info.py b/pandas/tests/frame/test_repr_info.py index 48f42b5f101ce..e02c7d6df2e72 100644 --- a/pandas/tests/frame/test_repr_info.py +++ b/pandas/tests/frame/test_repr_info.py @@ -206,6 +206,22 @@ def test_info(self): frame.info() frame.info(verbose=False) + def test_info_verbose(self): + buf = StringIO() + size = 5 + header_size = 3 + + frame = DataFrame(np.random.randn(3, size)) + frame.info(verbose=True, buf=buf) + + buf.seek(0) + lines = buf.readlines() + assert len(lines) > 0 + + for i, line in enumerate(lines): + if i >= header_size and i < header_size + size: + assert line.startswith(str(i - header_size) + ". ") + def test_info_memory(self): # https://github.com/pandas-dev/pandas/issues/21056 df = pd.DataFrame({"a": pd.Series([1, 2], dtype="i8")}) @@ -219,7 +235,7 @@ def test_info_memory(self): RangeIndex: 2 entries, 0 to 1 Data columns (total 1 columns): - a 2 non-null int64 + 0. a 2 non-null int64 dtypes: int64(1) memory usage: {} bytes """.format( @@ -263,8 +279,8 @@ def test_info_duplicate_columns_shows_correct_dtypes(self): frame.info(buf=io) io.seek(0) lines = io.readlines() - assert "a 1 non-null int64\n" == lines[3] - assert "a 1 non-null float64\n" == lines[4] + assert "0. a 1 non-null int64\n" == lines[3] + assert "1. a 1 non-null float64\n" == lines[4] def test_info_shows_column_dtypes(self): dtypes = [ From 6be1a9c956cba36558191ea9e92200faa61f66e9 Mon Sep 17 00:00:00 2001 From: Roy van Santen Date: Wed, 9 Oct 2019 21:02:29 +0200 Subject: [PATCH 02/15] Refactor code --- pandas/tests/frame/test_repr_info.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/pandas/tests/frame/test_repr_info.py b/pandas/tests/frame/test_repr_info.py index e02c7d6df2e72..9dd1458b74d49 100644 --- a/pandas/tests/frame/test_repr_info.py +++ b/pandas/tests/frame/test_repr_info.py @@ -209,8 +209,7 @@ def test_info(self): def test_info_verbose(self): buf = StringIO() size = 5 - header_size = 3 - + start = 3 frame = DataFrame(np.random.randn(3, size)) frame.info(verbose=True, buf=buf) @@ -219,8 +218,10 @@ def test_info_verbose(self): assert len(lines) > 0 for i, line in enumerate(lines): - if i >= header_size and i < header_size + size: - assert line.startswith(str(i - header_size) + ". ") + if i >= start and i < start + size: + index = i - start + line_nr = "{}. ".format(index) + assert line.startswith(line_nr) def test_info_memory(self): # https://github.com/pandas-dev/pandas/issues/21056 From af11450949b6c43b9c023acaadaff09154dbaf2e Mon Sep 17 00:00:00 2001 From: Roy van Santen Date: Wed, 9 Oct 2019 21:30:01 +0200 Subject: [PATCH 03/15] Add documentation --- doc/source/whatsnew/v0.25.2.rst | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/doc/source/whatsnew/v0.25.2.rst b/doc/source/whatsnew/v0.25.2.rst index 9789c9fce3541..a67ace4e15d18 100644 --- a/doc/source/whatsnew/v0.25.2.rst +++ b/doc/source/whatsnew/v0.25.2.rst @@ -97,6 +97,11 @@ Sparse - +Enhancements +^^^^^^^^^^^^ + +- Show line numbers when calling :meth:`DataFrame.info` with verbose flag on. (:issue:`17304`) + Other ^^^^^ From ced70a9b556c7ca23f5791ccf04cd9f64acb9360 Mon Sep 17 00:00:00 2001 From: Roy van Santen Date: Wed, 9 Oct 2019 21:37:07 +0200 Subject: [PATCH 04/15] Fix black pandas formatting --- pandas/core/frame.py | 5 ++++- pandas/tests/frame/test_repr_info.py | 2 +- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/pandas/core/frame.py b/pandas/core/frame.py index 27212b82cc512..9ae1941d6bc9e 100644 --- a/pandas/core/frame.py +++ b/pandas/core/frame.py @@ -2455,7 +2455,10 @@ def _verbose_repr(): count = counts.iloc[i] lines.append( - str(i) + ". " + _put_str(col, space) + tmpl.format(count=count, dtype=dtype) + str(i) + + ". " + + _put_str(col, space) + + tmpl.format(count=count, dtype=dtype) ) def _non_verbose_repr(): diff --git a/pandas/tests/frame/test_repr_info.py b/pandas/tests/frame/test_repr_info.py index 9dd1458b74d49..076e39c215a02 100644 --- a/pandas/tests/frame/test_repr_info.py +++ b/pandas/tests/frame/test_repr_info.py @@ -221,7 +221,7 @@ def test_info_verbose(self): if i >= start and i < start + size: index = i - start line_nr = "{}. ".format(index) - assert line.startswith(line_nr) + assert line.startswith(line_nr) def test_info_memory(self): # https://github.com/pandas-dev/pandas/issues/21056 From e3a2b4c1052c44e0300ef5c3b6f8455c5f7b3052 Mon Sep 17 00:00:00 2001 From: Roy van Santen Date: Fri, 11 Oct 2019 17:21:28 +0200 Subject: [PATCH 05/15] Align with PR 17332 --- dataframe.py | 9 +++++++++ pandas/core/frame.py | 32 +++++++++++++++++++++++--------- 2 files changed, 32 insertions(+), 9 deletions(-) create mode 100644 dataframe.py diff --git a/dataframe.py b/dataframe.py new file mode 100644 index 0000000000000..d90140d9cbde2 --- /dev/null +++ b/dataframe.py @@ -0,0 +1,9 @@ +import pandas as pd +import numpy as np +import sys + +data = pd.DataFrame(np.array([[1, 2, 3], [4, np.NaN, 6], [7, 8, 9]]), + columns=['asdfadsffdsafdsafsaa', 'b', 'c']) +print(data.info(verbose=True)) +print(data) +print(data.info()) \ No newline at end of file diff --git a/pandas/core/frame.py b/pandas/core/frame.py index 9ae1941d6bc9e..4f7df53969640 100644 --- a/pandas/core/frame.py +++ b/pandas/core/frame.py @@ -2415,6 +2415,7 @@ def info( return cols = self.columns + col_count = len(self.columns) # hack if max_cols is None: @@ -2423,17 +2424,22 @@ def info( max_rows = get_option("display.max_info_rows", len(self) + 1) if null_counts is None: - show_counts = (len(self.columns) <= max_cols) and (len(self) < max_rows) + show_counts = (col_count <= max_cols) and (len(self) < max_rows) else: show_counts = null_counts - exceeds_info_cols = len(self.columns) > max_cols + exceeds_info_cols = col_count > max_cols def _verbose_repr(): lines.append("Data columns (total %d columns):" % len(self.columns)) - space = max(len(pprint_thing(k)) for k in self.columns) + 4 + space = max(len(pprint_thing(k)) for k in cols) + len_column = len(pprint_thing('Column')) + space = max(space, len_column) + 4 + space_num = len(pprint_thing(col_count)) + len_id = len(pprint_thing(' #.')) + space_num = max(space_num, len_id) + 2 counts = None - tmpl = "{count}{dtype}" + header = _put_str(" # ", space_num) + _put_str("Column", space) if show_counts: counts = self.count() if len(cols) != len(counts): # pragma: no cover @@ -2443,20 +2449,28 @@ def _verbose_repr(): cols=len(cols), counts=len(counts) ) ) + col_header = 'Non-Null Count & Dtype' tmpl = "{count} non-null {dtype}" - - dtypes = self.dtypes + else: + col_header = 'Dtype' + tmpl = '{count}{dtype}' + header += col_header + + lines.append(header) + lines.append(_put_str('-' * len_id, space_num) + + _put_str('-' * len_column, space) + + '-' * len(pprint_thing(col_header))) for i, col in enumerate(self.columns): - dtype = dtypes.iloc[i] + dtype = self.dtypes.iloc[i] col = pprint_thing(col) + line_no = _put_str(' {num}'.format(num=i), space_num) count = "" if show_counts: count = counts.iloc[i] lines.append( - str(i) - + ". " + line_no + _put_str(col, space) + tmpl.format(count=count, dtype=dtype) ) From 3252a0a0c77493fa8d746a16ecff31d68971c3f1 Mon Sep 17 00:00:00 2001 From: Roy van Santen Date: Fri, 11 Oct 2019 22:15:10 +0200 Subject: [PATCH 06/15] Fix whatsnew, docstrings and test --- dataframe.py | 9 --- doc/source/whatsnew/v0.25.2.rst | 2 +- pandas/core/frame.py | 82 +++++++++++++++++++--------- pandas/tests/frame/test_repr_info.py | 24 ++++---- 4 files changed, 71 insertions(+), 46 deletions(-) delete mode 100644 dataframe.py diff --git a/dataframe.py b/dataframe.py deleted file mode 100644 index d90140d9cbde2..0000000000000 --- a/dataframe.py +++ /dev/null @@ -1,9 +0,0 @@ -import pandas as pd -import numpy as np -import sys - -data = pd.DataFrame(np.array([[1, 2, 3], [4, np.NaN, 6], [7, 8, 9]]), - columns=['asdfadsffdsafdsafsaa', 'b', 'c']) -print(data.info(verbose=True)) -print(data) -print(data.info()) \ No newline at end of file diff --git a/doc/source/whatsnew/v0.25.2.rst b/doc/source/whatsnew/v0.25.2.rst index a67ace4e15d18..14e81e7eefbdc 100644 --- a/doc/source/whatsnew/v0.25.2.rst +++ b/doc/source/whatsnew/v0.25.2.rst @@ -100,7 +100,7 @@ Sparse Enhancements ^^^^^^^^^^^^ -- Show line numbers when calling :meth:`DataFrame.info` with verbose flag on. (:issue:`17304`) +- :meth:`df.info()` now shows line numbers for the columns summary (:issue:`17304`) Other ^^^^^ diff --git a/pandas/core/frame.py b/pandas/core/frame.py index 4f7df53969640..edcc6147fb0d4 100644 --- a/pandas/core/frame.py +++ b/pandas/core/frame.py @@ -2343,9 +2343,11 @@ def info( RangeIndex: 5 entries, 0 to 4 Data columns (total 3 columns): - 0. int_col 5 non-null int64 - 1. text_col 5 non-null object - 2. float_col 5 non-null float64 + # Column Non-Null Count Dtype + --- ------ -------------- ----- + 0 int_col 5 non-null int64 + 1 text_col 5 non-null object + 2 float_col 5 non-null float64 dtypes: float64(1), int64(1), object(1) memory usage: 248.0+ bytes @@ -2384,9 +2386,11 @@ def info( RangeIndex: 1000000 entries, 0 to 999999 Data columns (total 3 columns): - column_1 1000000 non-null object - column_2 1000000 non-null object - column_3 1000000 non-null object + # Column Non-Null Count Dtype + --- ------ -------------- ----- + 0 column_1 1000000 non-null object + 1 column_2 1000000 non-null object + 2 column_3 1000000 non-null object dtypes: object(3) memory usage: 22.9+ MB @@ -2394,9 +2398,11 @@ def info( RangeIndex: 1000000 entries, 0 to 999999 Data columns (total 3 columns): - column_1 1000000 non-null object - column_2 1000000 non-null object - column_3 1000000 non-null object + # Column Non-Null Count Dtype + --- ------ -------------- ----- + 0 column_1 1000000 non-null object + 1 column_2 1000000 non-null object + 2 column_3 1000000 non-null object dtypes: object(3) memory usage: 188.8 MB """ @@ -2431,15 +2437,21 @@ def info( def _verbose_repr(): lines.append("Data columns (total %d columns):" % len(self.columns)) - space = max(len(pprint_thing(k)) for k in cols) - len_column = len(pprint_thing('Column')) - space = max(space, len_column) + 4 - space_num = len(pprint_thing(col_count)) - len_id = len(pprint_thing(' #.')) - space_num = max(space_num, len_id) + 2 + + id_head = " # " + column_head = "Column" + col_space = 2 + + max_col = max(len(pprint_thing(k)) for k in cols) + len_column = len(pprint_thing(column_head)) + space = max(max_col, len_column) + col_space + + max_id = len(pprint_thing(col_count)) + len_id = len(pprint_thing(id_head)) + space_num = max(max_id, len_id) + col_space counts = None - header = _put_str(" # ", space_num) + _put_str("Column", space) + header = _put_str(id_head, space_num) + _put_str(column_head, space) if show_counts: counts = self.count() if len(cols) != len(counts): # pragma: no cover @@ -2449,22 +2461,39 @@ def _verbose_repr(): cols=len(cols), counts=len(counts) ) ) - col_header = 'Non-Null Count & Dtype' - tmpl = "{count} non-null {dtype}" + count_header = "Non-Null Count" + len_count = len(count_header) + non_null = " non-null" + max_count = max(len(pprint_thing(k)) for k in counts) + len(non_null) + space_count = max(len_count, max_count) + col_space + count_temp = "{count}" + non_null else: - col_header = 'Dtype' - tmpl = '{count}{dtype}' - header += col_header + count_header = "" + space_count = len(count_header) + len_count = space_count + count_temp = "{count}" + + dtype_header = "Dtype" + len_dtype = len("Dtype") + max_dtypes = max(len(pprint_thing(k)) for k in self.dtypes) + space_dtype = max(len_dtype, max_dtypes) + header += _put_str(count_header, space_count) + _put_str( + dtype_header, space_dtype + ) lines.append(header) - lines.append(_put_str('-' * len_id, space_num) + - _put_str('-' * len_column, space) + - '-' * len(pprint_thing(col_header))) + lines.append( + _put_str("-" * len_id, space_num) + + _put_str("-" * len_column, space) + + _put_str("-" * len_count, space_count) + + _put_str("-" * len_dtype, space_dtype) + ) + for i, col in enumerate(self.columns): dtype = self.dtypes.iloc[i] col = pprint_thing(col) - line_no = _put_str(' {num}'.format(num=i), space_num) + line_no = _put_str(" {num}".format(num=i), space_num) count = "" if show_counts: count = counts.iloc[i] @@ -2472,7 +2501,8 @@ def _verbose_repr(): lines.append( line_no + _put_str(col, space) - + tmpl.format(count=count, dtype=dtype) + + _put_str(count_temp.format(count=count), space_count) + + _put_str(dtype, space_dtype) ) def _non_verbose_repr(): diff --git a/pandas/tests/frame/test_repr_info.py b/pandas/tests/frame/test_repr_info.py index 076e39c215a02..b9af4848c6da5 100644 --- a/pandas/tests/frame/test_repr_info.py +++ b/pandas/tests/frame/test_repr_info.py @@ -209,7 +209,7 @@ def test_info(self): def test_info_verbose(self): buf = StringIO() size = 5 - start = 3 + start = 5 frame = DataFrame(np.random.randn(3, size)) frame.info(verbose=True, buf=buf) @@ -220,7 +220,7 @@ def test_info_verbose(self): for i, line in enumerate(lines): if i >= start and i < start + size: index = i - start - line_nr = "{}. ".format(index) + line_nr = " {} ".format(index) assert line.startswith(line_nr) def test_info_memory(self): @@ -236,7 +236,9 @@ def test_info_memory(self): RangeIndex: 2 entries, 0 to 1 Data columns (total 1 columns): - 0. a 2 non-null int64 + # Column Non-Null Count Dtype + --- ------ -------------- ----- + 0 a 2 non-null int64 dtypes: int64(1) memory usage: {} bytes """.format( @@ -280,8 +282,8 @@ def test_info_duplicate_columns_shows_correct_dtypes(self): frame.info(buf=io) io.seek(0) lines = io.readlines() - assert "0. a 1 non-null int64\n" == lines[3] - assert "1. a 1 non-null float64\n" == lines[4] + assert " 0 a 1 non-null int64 \n" == lines[5] + assert " 1 a 1 non-null float64\n" == lines[6] def test_info_shows_column_dtypes(self): dtypes = [ @@ -302,12 +304,14 @@ def test_info_shows_column_dtypes(self): df.info(buf=buf) res = buf.getvalue() for i, dtype in enumerate(dtypes): - name = "{i:d} {n:d} non-null {dtype}".format(i=i, n=n, dtype=dtype) + name = " {i:d} {i:d} {n:d} non-null {dtype}".format( + i=i, n=n, dtype=dtype + ) assert name in res def test_info_max_cols(self): df = DataFrame(np.random.randn(10, 5)) - for len_, verbose in [(5, None), (5, False), (10, True)]: + for len_, verbose in [(5, None), (5, False), (12, True)]: # For verbose always ^ setting ^ summarize ^ full output with option_context("max_info_columns", 4): buf = StringIO() @@ -315,16 +319,16 @@ def test_info_max_cols(self): res = buf.getvalue() assert len(res.strip().split("\n")) == len_ - for len_, verbose in [(10, None), (5, False), (10, True)]: + for len_, verbose in [(12, None), (5, False), (12, True)]: - # max_cols no exceeded + # max_cols not exceeded with option_context("max_info_columns", 5): buf = StringIO() df.info(buf=buf, verbose=verbose) res = buf.getvalue() assert len(res.strip().split("\n")) == len_ - for len_, max_cols in [(10, 5), (5, 4)]: + for len_, max_cols in [(12, 5), (5, 4)]: # setting truncates with option_context("max_info_columns", 4): buf = StringIO() From ddff6d4ce15afd75843ba610dc53b2829ca610ef Mon Sep 17 00:00:00 2001 From: Roy van Santen Date: Sat, 12 Oct 2019 14:38:53 +0200 Subject: [PATCH 07/15] TST: test verbosity and long dtypes --- pandas/tests/frame/test_repr_info.py | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/pandas/tests/frame/test_repr_info.py b/pandas/tests/frame/test_repr_info.py index b9af4848c6da5..aac32448651f5 100644 --- a/pandas/tests/frame/test_repr_info.py +++ b/pandas/tests/frame/test_repr_info.py @@ -208,11 +208,17 @@ def test_info(self): def test_info_verbose(self): buf = StringIO() - size = 5 + size = 1001 start = 5 frame = DataFrame(np.random.randn(3, size)) frame.info(verbose=True, buf=buf) + res = buf.getvalue() + header = " # Column Dtype \n" \ + "--- ------ ----- " + assert header in res + + frame.info(verbose=True, buf=buf) buf.seek(0) lines = buf.readlines() assert len(lines) > 0 @@ -303,6 +309,9 @@ def test_info_shows_column_dtypes(self): buf = StringIO() df.info(buf=buf) res = buf.getvalue() + header = " # Column Non-Null Count Dtype \n" \ + "--- ------ -------------- ----- " + assert header in res for i, dtype in enumerate(dtypes): name = " {i:d} {i:d} {n:d} non-null {dtype}".format( i=i, n=n, dtype=dtype From b28370df5b4845b96646ea9caf0f3d0d2a0b99b4 Mon Sep 17 00:00:00 2001 From: Roy van Santen Date: Sat, 12 Oct 2019 14:44:20 +0200 Subject: [PATCH 08/15] DOC: move enhancement to 1.0.0 --- doc/source/whatsnew/v0.25.2.rst | 5 ----- doc/source/whatsnew/v1.0.0.rst | 2 ++ 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/doc/source/whatsnew/v0.25.2.rst b/doc/source/whatsnew/v0.25.2.rst index 14e81e7eefbdc..9789c9fce3541 100644 --- a/doc/source/whatsnew/v0.25.2.rst +++ b/doc/source/whatsnew/v0.25.2.rst @@ -97,11 +97,6 @@ Sparse - -Enhancements -^^^^^^^^^^^^ - -- :meth:`df.info()` now shows line numbers for the columns summary (:issue:`17304`) - Other ^^^^^ diff --git a/doc/source/whatsnew/v1.0.0.rst b/doc/source/whatsnew/v1.0.0.rst index 751db2b88069d..1f0e4d919fac9 100644 --- a/doc/source/whatsnew/v1.0.0.rst +++ b/doc/source/whatsnew/v1.0.0.rst @@ -50,6 +50,8 @@ including other versions of pandas. Enhancements ~~~~~~~~~~~~ +- :meth:`Dataframe.info` now shows line numbers for the columns summary (:issue:`17304`) + .. _whatsnew_100.string: Dedicated string data type From a2858452b6fb8f90121070453b87dc93e5abe4f3 Mon Sep 17 00:00:00 2001 From: Roy van Santen Date: Sat, 12 Oct 2019 14:44:43 +0200 Subject: [PATCH 09/15] CLN: black pandas formatting --- pandas/tests/frame/test_repr_info.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/pandas/tests/frame/test_repr_info.py b/pandas/tests/frame/test_repr_info.py index aac32448651f5..42e5eb7c0665b 100644 --- a/pandas/tests/frame/test_repr_info.py +++ b/pandas/tests/frame/test_repr_info.py @@ -214,8 +214,7 @@ def test_info_verbose(self): frame.info(verbose=True, buf=buf) res = buf.getvalue() - header = " # Column Dtype \n" \ - "--- ------ ----- " + header = " # Column Dtype \n" "--- ------ ----- " assert header in res frame.info(verbose=True, buf=buf) @@ -309,8 +308,10 @@ def test_info_shows_column_dtypes(self): buf = StringIO() df.info(buf=buf) res = buf.getvalue() - header = " # Column Non-Null Count Dtype \n" \ - "--- ------ -------------- ----- " + header = ( + " # Column Non-Null Count Dtype \n" + "--- ------ -------------- ----- " + ) assert header in res for i, dtype in enumerate(dtypes): name = " {i:d} {i:d} {n:d} non-null {dtype}".format( From 1fd835d7537a72e84ee59a3cdf3f046096efddcb Mon Sep 17 00:00:00 2001 From: Roy van Santen Date: Fri, 25 Oct 2019 22:31:29 +0200 Subject: [PATCH 10/15] CLN: replace string --- pandas/core/frame.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pandas/core/frame.py b/pandas/core/frame.py index edcc6147fb0d4..38457ba3738ab 100644 --- a/pandas/core/frame.py +++ b/pandas/core/frame.py @@ -2474,7 +2474,7 @@ def _verbose_repr(): count_temp = "{count}" dtype_header = "Dtype" - len_dtype = len("Dtype") + len_dtype = len(dtype_header) max_dtypes = max(len(pprint_thing(k)) for k in self.dtypes) space_dtype = max(len_dtype, max_dtypes) header += _put_str(count_header, space_count) + _put_str( From 7cd6f1e419c877e761af70f855f78b541b473bf1 Mon Sep 17 00:00:00 2001 From: Roy van Santen Date: Thu, 7 Nov 2019 20:36:16 +0100 Subject: [PATCH 11/15] CLN: refactor to use string formatting --- pandas/core/frame.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pandas/core/frame.py b/pandas/core/frame.py index 38457ba3738ab..389d59a8f3335 100644 --- a/pandas/core/frame.py +++ b/pandas/core/frame.py @@ -2436,7 +2436,7 @@ def info( exceeds_info_cols = col_count > max_cols def _verbose_repr(): - lines.append("Data columns (total %d columns):" % len(self.columns)) + lines.append("Data columns (total {} columns):".format(len(self.columns))) id_head = " # " column_head = "Column" From d9e3932d81d5a2ae2eaee56da86ef3998b0f48fe Mon Sep 17 00:00:00 2001 From: Roy van Santen Date: Thu, 7 Nov 2019 21:28:08 +0100 Subject: [PATCH 12/15] DOC: add output example to api breaking changes --- doc/source/whatsnew/v1.0.0.rst | 28 ++++++++++++++++++++++++++-- 1 file changed, 26 insertions(+), 2 deletions(-) diff --git a/doc/source/whatsnew/v1.0.0.rst b/doc/source/whatsnew/v1.0.0.rst index 1f0e4d919fac9..10c2e8c991cea 100644 --- a/doc/source/whatsnew/v1.0.0.rst +++ b/doc/source/whatsnew/v1.0.0.rst @@ -50,8 +50,6 @@ including other versions of pandas. Enhancements ~~~~~~~~~~~~ -- :meth:`Dataframe.info` now shows line numbers for the columns summary (:issue:`17304`) - .. _whatsnew_100.string: Dedicated string data type @@ -145,6 +143,32 @@ Backwards incompatible API changes pd.arrays.IntervalArray.from_tuples([(0, 1), (2, 3)]) +- :meth:`Dataframe.info` now shows line numbers for the columns summary (:issue:`17304`) + +*pandas 0.25.x* + +.. code-block:: ipython + + In [1]: df = pd.DataFrame({"int_col": [1, 2, 3], "text_col": ["a", "b", "c"], + ... "float_col": [0.0, 0.1, 0.2]}) + In [2]: df.info(verbose=True) + Out[3]: + + RangeIndex: 3 entries, 0 to 2 + Data columns (total 3 columns): + int_col 3 non-null int64 + text_col 3 non-null object + float_col 3 non-null float64 + dtypes: float64(1), int64(1), object(1) + memory usage: 152.0+ bytes + + +*pandas 1.0.0* + +.. ipython:: python + + df = pd.DataFrame({"int_col": [1, 2, 3], "text_col": ["a", "b", "c"], "float_col": [0.0, 0.1, 0.2]}) + df.info(verbose=True) .. _whatsnew_1000.api.other: From ff4b2ed20c96cc4706a784d5a4cc26f26b10c7ca Mon Sep 17 00:00:00 2001 From: Roy van Santen Date: Tue, 31 Dec 2019 15:12:42 +0100 Subject: [PATCH 13/15] CLN: fix doc line too long --- doc/source/whatsnew/v1.0.0.rst | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/doc/source/whatsnew/v1.0.0.rst b/doc/source/whatsnew/v1.0.0.rst index 7c2c618e2aa04..5d9cf785b4a18 100755 --- a/doc/source/whatsnew/v1.0.0.rst +++ b/doc/source/whatsnew/v1.0.0.rst @@ -316,7 +316,9 @@ New repr for :class:`~pandas.arrays.IntervalArray` .. ipython:: python - df = pd.DataFrame({"int_col": [1, 2, 3], "text_col": ["a", "b", "c"], "float_col": [0.0, 0.1, 0.2]}) + df = pd.DataFrame({"int_col": [1, 2, 3], + "text_col": ["a", "b", "c"], + "float_col": [0.0, 0.1, 0.2]}) df.info(verbose=True) All :class:`SeriesGroupBy` aggregation methods now respect the ``observed`` keyword From 8a67d9c48ab0e99589e0ebd0cce65460a864a018 Mon Sep 17 00:00:00 2001 From: Roy van Santen Date: Thu, 2 Jan 2020 11:05:43 +0100 Subject: [PATCH 14/15] DOC: add info feature title --- doc/source/whatsnew/v1.0.0.rst | 31 ++++++++++++++++--------------- 1 file changed, 16 insertions(+), 15 deletions(-) diff --git a/doc/source/whatsnew/v1.0.0.rst b/doc/source/whatsnew/v1.0.0.rst index 5d9cf785b4a18..3a8790f62d01f 100755 --- a/doc/source/whatsnew/v1.0.0.rst +++ b/doc/source/whatsnew/v1.0.0.rst @@ -285,32 +285,33 @@ New repr for :class:`~pandas.arrays.IntervalArray` closed='right', dtype='interval[int64]') - *pandas 1.0.0* .. ipython:: python pd.arrays.IntervalArray.from_tuples([(0, 1), (2, 3)]) +Extended verbose info output for :class:`~pandas.DataFrame` +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + - :meth:`Dataframe.info` now shows line numbers for the columns summary (:issue:`17304`) *pandas 0.25.x* -.. code-block:: ipython - - In [1]: df = pd.DataFrame({"int_col": [1, 2, 3], "text_col": ["a", "b", "c"], - ... "float_col": [0.0, 0.1, 0.2]}) - In [2]: df.info(verbose=True) - Out[3]: - - RangeIndex: 3 entries, 0 to 2 - Data columns (total 3 columns): - int_col 3 non-null int64 - text_col 3 non-null object - float_col 3 non-null float64 - dtypes: float64(1), int64(1), object(1) - memory usage: 152.0+ bytes +.. code-block:: python + >>> df = pd.DataFrame({"int_col": [1, 2, 3], + ... "text_col": ["a", "b", "c"], + ... "float_col": [0.0, 0.1, 0.2]}) + >>> df.info(verbose=True) + + RangeIndex: 3 entries, 0 to 2 + Data columns (total 3 columns): + int_col 3 non-null int64 + text_col 3 non-null object + float_col 3 non-null float64 + dtypes: float64(1), int64(1), object(1) + memory usage: 152.0+ bytes *pandas 1.0.0* From 4e556ae61a99747337cd21c08eba79733817f9e8 Mon Sep 17 00:00:00 2001 From: Tom Augspurger Date: Thu, 2 Jan 2020 14:40:50 -0600 Subject: [PATCH 15/15] fixup --- pandas/tests/frame/test_repr_info.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pandas/tests/frame/test_repr_info.py b/pandas/tests/frame/test_repr_info.py index c3a605e2fe544..91610102cf0f9 100644 --- a/pandas/tests/frame/test_repr_info.py +++ b/pandas/tests/frame/test_repr_info.py @@ -213,7 +213,7 @@ def test_info_verbose(self): frame.info(verbose=True, buf=buf) res = buf.getvalue() - header = " # Column Dtype \n" "--- ------ ----- " + header = " # Column Dtype \n--- ------ ----- " assert header in res frame.info(verbose=True, buf=buf)