From 809197fe9cfb601a9fca2ff4faffa70713547dec Mon Sep 17 00:00:00 2001 From: Tom Augspurger Date: Sun, 27 Jan 2019 15:52:13 -0600 Subject: [PATCH 1/3] Fixed itertuples usage in to_dict Closes https://github.com/pandas-dev/pandas/issues/24940 Closes https://github.com/pandas-dev/pandas/issues/24939 --- doc/source/whatsnew/v0.24.1.rst | 4 ++-- pandas/core/frame.py | 7 +++++-- pandas/tests/frame/test_convert_to.py | 14 ++++++++++++++ 3 files changed, 21 insertions(+), 4 deletions(-) diff --git a/doc/source/whatsnew/v0.24.1.rst b/doc/source/whatsnew/v0.24.1.rst index 3ac2ed73ea53f..0e03b09d520ed 100644 --- a/doc/source/whatsnew/v0.24.1.rst +++ b/doc/source/whatsnew/v0.24.1.rst @@ -29,8 +29,8 @@ Bug Fixes **Conversion** -- -- +- Bug in :meth:`DataFrame.itertuples` with ``records`` orient raising an AttributeError when the ``DataFrame`` contained more than 255 columns (:issue:`24939`) +- Bug in :meth:`DataFrame.itertuples` orient converting integer column names to strings prepended with an underscore (:issue:`24940`) - **Indexing** diff --git a/pandas/core/frame.py b/pandas/core/frame.py index b4f79bda25517..c923a65f2f766 100644 --- a/pandas/core/frame.py +++ b/pandas/core/frame.py @@ -1296,10 +1296,13 @@ def to_dict(self, orient='dict', into=dict): return into_c((k, com.maybe_box_datetimelike(v)) for k, v in compat.iteritems(self)) elif orient.lower().startswith('r'): + columns = self.columns.tolist() + rows = (dict(zip(columns, row)) + for row in self.itertuples(index=False)) return [ into_c((k, com.maybe_box_datetimelike(v)) - for k, v in compat.iteritems(row._asdict())) - for row in self.itertuples(index=False)] + for k, v in compat.iteritems(row)) + for row in rows] elif orient.lower().startswith('i'): if not self.index.is_unique: raise ValueError( diff --git a/pandas/tests/frame/test_convert_to.py b/pandas/tests/frame/test_convert_to.py index ddf85136126a1..8f74cbfcc3d99 100644 --- a/pandas/tests/frame/test_convert_to.py +++ b/pandas/tests/frame/test_convert_to.py @@ -488,3 +488,17 @@ def test_to_dict_index_dtypes(self, into, expected): result = DataFrame.from_dict(result, orient='index')[cols] expected = DataFrame.from_dict(expected, orient='index')[cols] tm.assert_frame_equal(result, expected) + + def test_to_dict_numeric_names(self): + # https://github.com/pandas-dev/pandas/issues/24940 + df = DataFrame({str(i): [i] for i in range(5)}) + result = set(df.to_dict('records')[0].keys()) + expected = set(df.columns) + assert result == expected + + def test_to_dict_wide(self): + # https://github.com/pandas-dev/pandas/issues/24939 + df = DataFrame({('A_%d' % i): [i] for i in range(256)}) + result = df.to_dict('records')[0] + expected = {'A_{:d}'.format(i): i for i in range(256)} + assert result == expected From e500256d68123cf3b3e545712afa2bf39722dff5 Mon Sep 17 00:00:00 2001 From: Tom Augspurger Date: Mon, 28 Jan 2019 07:22:45 -0600 Subject: [PATCH 2/3] updates --- doc/source/whatsnew/v0.24.1.rst | 11 +++++++++-- pandas/core/frame.py | 10 +++++----- 2 files changed, 14 insertions(+), 7 deletions(-) diff --git a/doc/source/whatsnew/v0.24.1.rst b/doc/source/whatsnew/v0.24.1.rst index 0e03b09d520ed..de33ce64c1597 100644 --- a/doc/source/whatsnew/v0.24.1.rst +++ b/doc/source/whatsnew/v0.24.1.rst @@ -15,6 +15,13 @@ Whats New in 0.24.1 (February XX, 2019) These are the changes in pandas 0.24.1. See :ref:`release` for a full changelog including other versions of pandas. +.. _whatsnew_0241.regressions: + +Fixed Regressions +^^^^^^^^^^^^^^^^^ + +- Bug in :meth:`DataFrame.itertuples` with ``records`` orient raising an ``AttributeError`` when the ``DataFrame`` contained more than 255 columns (:issue:`24939`) +- Bug in :meth:`DataFrame.itertuples` orient converting integer column names to strings prepended with an underscore (:issue:`24940`) .. _whatsnew_0241.enhancements: @@ -29,8 +36,8 @@ Bug Fixes **Conversion** -- Bug in :meth:`DataFrame.itertuples` with ``records`` orient raising an AttributeError when the ``DataFrame`` contained more than 255 columns (:issue:`24939`) -- Bug in :meth:`DataFrame.itertuples` orient converting integer column names to strings prepended with an underscore (:issue:`24940`) +- +- - **Indexing** diff --git a/pandas/core/frame.py b/pandas/core/frame.py index c923a65f2f766..28c6f3c23a3ce 100644 --- a/pandas/core/frame.py +++ b/pandas/core/frame.py @@ -847,7 +847,7 @@ def itertuples(self, index=True, name="Pandas"): ---------- index : bool, default True If True, return the index as the first element of the tuple. - name : str, default "Pandas" + name : str or None, default "Pandas" The name of the returned namedtuples or None to return regular tuples. @@ -1290,15 +1290,15 @@ def to_dict(self, orient='dict', into=dict): ('columns', self.columns.tolist()), ('data', [ list(map(com.maybe_box_datetimelike, t)) - for t in self.itertuples(index=False)] - ))) + for t in self.itertuples(index=False, name=None) + ]))) elif orient.lower().startswith('s'): return into_c((k, com.maybe_box_datetimelike(v)) for k, v in compat.iteritems(self)) elif orient.lower().startswith('r'): columns = self.columns.tolist() rows = (dict(zip(columns, row)) - for row in self.itertuples(index=False)) + for row in self.itertuples(index=False, name=None)) return [ into_c((k, com.maybe_box_datetimelike(v)) for k, v in compat.iteritems(row)) @@ -1309,7 +1309,7 @@ def to_dict(self, orient='dict', into=dict): "DataFrame index must be unique for orient='index'." ) return into_c((t[0], dict(zip(self.columns, t[1:]))) - for t in self.itertuples()) + for t in self.itertuples(name=None)) else: raise ValueError("orient '{o}' not understood".format(o=orient)) From 08ea491e6b6c191db7965cf293e034466001fc2c Mon Sep 17 00:00:00 2001 From: Tom Augspurger Date: Mon, 28 Jan 2019 07:42:03 -0600 Subject: [PATCH 3/3] fixup --- pandas/tests/frame/test_convert_to.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pandas/tests/frame/test_convert_to.py b/pandas/tests/frame/test_convert_to.py index 8f74cbfcc3d99..7b98395dd6dec 100644 --- a/pandas/tests/frame/test_convert_to.py +++ b/pandas/tests/frame/test_convert_to.py @@ -498,7 +498,7 @@ def test_to_dict_numeric_names(self): def test_to_dict_wide(self): # https://github.com/pandas-dev/pandas/issues/24939 - df = DataFrame({('A_%d' % i): [i] for i in range(256)}) + df = DataFrame({('A_{:d}'.format(i)): [i] for i in range(256)}) result = df.to_dict('records')[0] expected = {'A_{:d}'.format(i): i for i in range(256)} assert result == expected