Skip to content

Commit 13c9601

Browse files
simongibbonsjreback
authored andcommitted
BUG: Ensure df.itertuples() uses plain tuples correctly (pandas-dev#30600)
1 parent 3755762 commit 13c9601

File tree

3 files changed

+29
-4
lines changed

3 files changed

+29
-4
lines changed

doc/source/whatsnew/v1.0.0.rst

+1
Original file line numberDiff line numberDiff line change
@@ -988,6 +988,7 @@ Other
988988
- Bug in :class:`Index` where a non-hashable name could be set without raising ``TypeError`` (:issue:`29069`)
989989
- Bug in :class:`DataFrame` constructor when passing a 2D ``ndarray`` and an extension dtype (:issue:`12513`)
990990
- Bug in :meth:`DaataFrame.to_csv` when supplied a series with a ``dtype="string"`` and a ``na_rep``, the ``na_rep`` was being truncated to 2 characters. (:issue:`29975`)
991+
- Bug where :meth:`DataFrame.itertuples` would incorrectly determine whether or not namedtuples could be used for dataframes of 255 columns (:issue:`28282`)
991992

992993
.. _whatsnew_1000.contributors:
993994

pandas/core/frame.py

+6-3
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@
3838

3939
from pandas._libs import algos as libalgos, lib
4040
from pandas._typing import Axes, Dtype, FilePathOrBuffer
41+
from pandas.compat import PY37
4142
from pandas.compat._optional import import_optional_dependency
4243
from pandas.compat.numpy import function as nv
4344
from pandas.util._decorators import (
@@ -975,7 +976,8 @@ def itertuples(self, index=True, name="Pandas"):
975976
-----
976977
The column names will be renamed to positional names if they are
977978
invalid Python identifiers, repeated, or start with an underscore.
978-
With a large number of columns (>255), regular tuples are returned.
979+
On python versions < 3.7 regular tuples are returned for DataFrames
980+
with a large number of columns (>254).
979981
980982
Examples
981983
--------
@@ -1018,8 +1020,9 @@ def itertuples(self, index=True, name="Pandas"):
10181020
# use integer indexing because of possible duplicate column names
10191021
arrays.extend(self.iloc[:, k] for k in range(len(self.columns)))
10201022

1021-
# Python 3 supports at most 255 arguments to constructor
1022-
if name is not None and len(self.columns) + index < 256:
1023+
# Python versions before 3.7 support at most 255 arguments to constructors
1024+
can_return_named_tuples = PY37 or len(self.columns) + index < 255
1025+
if name is not None and can_return_named_tuples:
10231026
itertuple = collections.namedtuple(name, fields, rename=True)
10241027
return map(itertuple._make, zip(*arrays))
10251028

pandas/tests/frame/test_api.py

+22-1
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@
55
import numpy as np
66
import pytest
77

8+
from pandas.compat import PY37
9+
810
import pandas as pd
911
from pandas import Categorical, DataFrame, Series, compat, date_range, timedelta_range
1012
import pandas.util.testing as tm
@@ -261,8 +263,27 @@ def test_itertuples(self, float_frame):
261263
df3 = DataFrame({"f" + str(i): [i] for i in range(1024)})
262264
# will raise SyntaxError if trying to create namedtuple
263265
tup3 = next(df3.itertuples())
264-
assert not hasattr(tup3, "_fields")
265266
assert isinstance(tup3, tuple)
267+
if PY37:
268+
assert hasattr(tup3, "_fields")
269+
else:
270+
assert not hasattr(tup3, "_fields")
271+
272+
# GH 28282
273+
df_254_columns = DataFrame([{f"foo_{i}": f"bar_{i}" for i in range(254)}])
274+
result_254_columns = next(df_254_columns.itertuples(index=False))
275+
assert isinstance(result_254_columns, tuple)
276+
assert hasattr(result_254_columns, "_fields")
277+
278+
df_255_columns = DataFrame([{f"foo_{i}": f"bar_{i}" for i in range(255)}])
279+
result_255_columns = next(df_255_columns.itertuples(index=False))
280+
assert isinstance(result_255_columns, tuple)
281+
282+
# Dataframes with >=255 columns will fallback to regular tuples on python < 3.7
283+
if PY37:
284+
assert hasattr(result_255_columns, "_fields")
285+
else:
286+
assert not hasattr(result_255_columns, "_fields")
266287

267288
def test_sequence_like_with_categorical(self):
268289

0 commit comments

Comments
 (0)