diff --git a/asv_bench/benchmarks/frame_methods.py b/asv_bench/benchmarks/frame_methods.py index a04a9d0814a30..2c07c28066faf 100644 --- a/asv_bench/benchmarks/frame_methods.py +++ b/asv_bench/benchmarks/frame_methods.py @@ -653,6 +653,16 @@ def j(self): self.df3[0] +class frame_itertuples(object): + + def setup(self): + self.df = DataFrame(np.random.randn(50000, 10)) + + def time_frame_itertuples(self): + for row in self.df.itertuples(): + pass + + class frame_mask_bools(object): goal_time = 0.2 diff --git a/doc/source/conf.py b/doc/source/conf.py index 23095b7f4d24b..304348917c36c 100644 --- a/doc/source/conf.py +++ b/doc/source/conf.py @@ -309,6 +309,8 @@ # extlinks alias extlinks = {'issue': ('https://github.com/pydata/pandas/issues/%s', 'GH'), + 'pr': ('https://github.com/pydata/pandas/pull/%s', + 'GH-PR'), 'wiki': ('https://github.com/pydata/pandas/wiki/%s', 'wiki ')} diff --git a/doc/source/whatsnew/v0.17.1.txt b/doc/source/whatsnew/v0.17.1.txt index 046791d4287c9..be68e9e8de2ce 100755 --- a/doc/source/whatsnew/v0.17.1.txt +++ b/doc/source/whatsnew/v0.17.1.txt @@ -80,7 +80,7 @@ API changes - Indexing with a null key will raise a ``TypeError``, instead of a ``ValueError`` (:issue:`11356`) - ``Series.sort_index()`` now correctly handles the ``inplace`` option (:issue:`11402`) -- ``DataFrame.itertuples()`` now returns ``namedtuple`` objects, when possible. (:issue:`11269`) +- ``DataFrame.itertuples()`` now returns ``namedtuple`` objects, when possible. (:issue:`11269`, :pr:`11625`) - ``Series.ptp`` will now ignore missing values by default (:issue:`11163`) .. _whatsnew_0171.deprecations: diff --git a/pandas/core/frame.py b/pandas/core/frame.py index 5447574c9ea4e..81da1223f50d5 100644 --- a/pandas/core/frame.py +++ b/pandas/core/frame.py @@ -43,7 +43,7 @@ import pandas.computation.expressions as expressions from pandas.computation.eval import eval as _eval from numpy import percentile as _quantile -from pandas.compat import(range, zip, lrange, lmap, lzip, StringIO, u, +from pandas.compat import(range, map, zip, lrange, lmap, lzip, StringIO, u, OrderedDict, raise_with_traceback) from pandas import compat from pandas.sparse.array import SparseArray @@ -664,7 +664,7 @@ def itertuples(self, index=True, name="Pandas"): index : boolean, default True If True, return the index as the first element of the tuple. name : string, default "Pandas" - The name of the returned namedtuple. + The name of the returned namedtuples or None to return regular tuples. Notes ----- @@ -703,13 +703,13 @@ def itertuples(self, index=True, name="Pandas"): # Python 3 supports at most 255 arguments to constructor, and # things get slow with this many fields in Python 2 - if len(self.columns) + index < 256: + if name is not None and len(self.columns) + index < 256: # `rename` is unsupported in Python 2.6 try: itertuple = collections.namedtuple( name, fields+list(self.columns), rename=True) - return (itertuple(*row) for row in zip(*arrays)) - except: + return map(itertuple._make, zip(*arrays)) + except Exception: pass # fallback to regular tuples diff --git a/pandas/tests/test_frame.py b/pandas/tests/test_frame.py index a743ce4ffef61..ae0424c8fcbd1 100644 --- a/pandas/tests/test_frame.py +++ b/pandas/tests/test_frame.py @@ -5545,6 +5545,8 @@ def test_itertuples(self): dfaa = df[['a', 'a']] self.assertEqual(list(dfaa.itertuples()), [(0, 1, 1), (1, 2, 2), (2, 3, 3)]) + self.assertEqual(repr(list(df.itertuples(name=None))), '[(0, 1, 4), (1, 2, 5), (2, 3, 6)]') + tup = next(df.itertuples(name='TestName')) # no support for field renaming in Python 2.6, regular tuples are returned