PERF: speed-up DateFrame.itertuples() with namedtuples
State: closed

- use [namedtuple._make()](https://docs.python.org/2/library/collections.html#collections.somenamedtuple._make)

Also:
- replace bare `except:` to avoid catching `SystemExit` and `KeyboardInterrupt`
- remove the generator `return` from the `try`-clause to an `else`
- more explicit fallback to regular tuples when `name=None` (docs?)


Labels:
name: Performance
description: Memory or execution speed performance

Comments:
you would have to add a benchmark for this
though u r using a private function so u less this is a huge speed up prob not worth it
need a test for name=None 
don't use an else clause - just put in the try - what u added is much less explicit 

As fas as I can see, `_make()` is the preferred way of creating a `namedtuple` from an iterable (i.e. although it starts with an underscore, it is **not** a private method):

> In addition to the methods inherited from tuples, named tuples support three additional methods
> and one attribute. To prevent conflicts with field names, the method and attribute names start with
> an underscore.

I disagree, to me this is exactly what the `else`-clause of `try...except` is for. Why have a bare `try` around the generator expression?

> The use of the else clause is better than adding additional code to the try clause because it avoids
> accidentally catching an exception that wasn’t raised by the code being protected by the
> try ... except statement.

Here are some simple timings:

``` python
import collections

import pandas as pd
from pandas.compat import map, zip

class DataFrame(pd.DataFrame):

    def itertuples_new(self, index=True, name="Pandas"):
(...)
            else:
                return (itertuple(*row) for row in zip(*arrays))

        # fallback to regular tuples
        return zip(*arrays)

    def itertuples_make(self, index=True, name="Pandas"):
(...)
            else:
                return map(itertuple._make, zip(*arrays))

        # fallback to regular tuples
        return zip(*arrays)

df = DataFrame({'A': 'spam', 'B': range(1000), 'C': None,
   'D': range(1000), 'E': range(1000), 'F': range(1000)})

%timeit list(df.itertuples_new())
100 loops, best of 3: 3.04 ms per loop

%timeit list(df.itertuples_make())
100 loops, best of 3: 2.68 ms per loop

%timeit list(df.itertuples_make(name=None))
1000 loops, best of 3: 1.17 ms per loop
```

pls add a benchmark to the asv suite (make about 10x bigger).

``` bash
$ asv continuous master HEAD -b
 frame_methods.frame_itertuples
· Creating environments
· Discovering benchmarks
·· Uninstalling from py2.7-Cython-matplotlib-numexpr-numpy-openpyxl-pytables-sci
py-sqlalchemy-xlrd-xlsxwriter-xlwt
·· Building for py2.7-Cython-matplotlib-numexpr-numpy-openpyxl-pytables-scipy-sq
lalchemy-xlrd-xlsxwriter-xlwt
·· Installing into py2.7-Cython-matplotlib-numexpr-numpy-openpyxl-pytables-scipy
-sqlalchemy-xlrd-xlsxwriter-xlwt
· Running 2 total benchmarks (2 commits * 1 environments * 1 benchmarks)
[  0.00%] · For pandas commit hash 2238f73e:
[  0.00%] ·· Building for py2.7-Cython-matplotlib-numexpr-numpy-openpyxl-pytable
s-scipy-sqlalchemy-xlrd-xlsxwriter-xlwt
[  0.00%] ·· Benchmarking py2.7-Cython-matplotlib-numexpr-numpy-openpyxl-pytable
s-scipy-sqlalchemy-xlrd-xlsxwriter-xlwt
[ 50.00%] ··· Running ...thods.frame_itertuples.time_frame_itertuples   10.03ms
[ 50.00%] · For pandas commit hash e29bf614:
[ 50.00%] ·· Building for py2.7-Cython-matplotlib-numexpr-numpy-openpyxl-pytable
s-scipy-sqlalchemy-xlrd-xlsxwriter-xlwt
[ 50.00%] ·· Benchmarking py2.7-Cython-matplotlib-numexpr-numpy-openpyxl-pytable
s-scipy-sqlalchemy-xlrd-xlsxwriter-xlwt
[100.00%] ··· Running ...thods.frame_itertuples.time_frame_itertuples   12.24msB
ENCHMARKS NOT SIGNIFICANTLY CHANGED.
```

```
[ 50.00%] ··· Running ...thods.frame_itertuples.time_frame_itertuples   77.15ms
[100.00%] ··· Running ...thods.frame_itertuples.time_frame_itertuples  103.37ms
```

Okay, maybe one last try to reconsider your dislike of `try...else`-clauses.
Apart from the official docs, there also seems to be [some](https://stackoverflow.com/questions/855759/python-try-else) [others](https://stackoverflow.com/questions/16138232/is-it-a-good-practice-to-use-try-except-else-in-python) in favour.

@xflr6 pls just follow my directions. It has nothing to do with whether I like it or not. Its not consistent at all in the code base.

Performance comparison with the regular tuple returning branch:

```
[ 25.00%] ··· Running ...thods.frame_itertuples.time_frame_itertuples   76.64ms
[ 50.00%] ··· Running ...ame_itertuples.time_frame_itertuples_regular   38.04ms
```

ok, add this issue number onto where #11269 is in whatsnew/v0.17.0
squash to a single commit. ping when green.

There is no issue for this (only the PR), should I open one?

no use the pr number

merged via https://github.com/pydata/pandas/commit/4ffc3efaf91c4a70a95f46bbf6344cb629bd688f

thanks!