Skip to content

Commit 9fbb9e7

Browse files
sighingnowjreback
authored andcommitted
BUG: Convert tuple to list before _list_to_arrays when construct DataFrame. (#25731)
1 parent b974633 commit 9fbb9e7

File tree

3 files changed

+36
-8
lines changed

3 files changed

+36
-8
lines changed

doc/source/whatsnew/v0.25.0.rst

+1
Original file line numberDiff line numberDiff line change
@@ -393,6 +393,7 @@ Reshaping
393393
- Bug in :func:`concat` where order of ``OrderedDict`` (and ``dict`` in Python 3.6+) is not respected, when passed in as ``objs`` argument (:issue:`21510`)
394394
- Bug in :func:`concat` where the resulting ``freq`` of two :class:`DatetimeIndex` with the same ``freq`` would be dropped (:issue:`3232`).
395395
- Bug in :func:`merge` where merging with equivalent Categorical dtypes was raising an error (:issue:`22501`)
396+
- Bug in :class:`DataFrame` constructor when passing non-empty tuples would cause a segmentation fault (:issue:`25691`)
396397

397398
Sparse
398399
^^^^^^

pandas/_libs/lib.pyx

+19-6
Original file line numberDiff line numberDiff line change
@@ -2264,22 +2264,21 @@ def to_object_array(rows: object, int min_width=0):
22642264
cdef:
22652265
Py_ssize_t i, j, n, k, tmp
22662266
ndarray[object, ndim=2] result
2267-
list input_rows
22682267
list row
22692268

2270-
input_rows = <list>rows
2271-
n = len(input_rows)
2269+
rows = list(rows)
2270+
n = len(rows)
22722271

22732272
k = min_width
22742273
for i in range(n):
2275-
tmp = len(input_rows[i])
2274+
tmp = len(rows[i])
22762275
if tmp > k:
22772276
k = tmp
22782277

22792278
result = np.empty((n, k), dtype=object)
22802279

22812280
for i in range(n):
2282-
row = list(input_rows[i])
2281+
row = list(rows[i])
22832282

22842283
for j in range(len(row)):
22852284
result[i, j] = row[j]
@@ -2304,12 +2303,26 @@ def tuples_to_object_array(ndarray[object] tuples):
23042303
return result
23052304

23062305

2307-
def to_object_array_tuples(rows: list):
2306+
def to_object_array_tuples(rows: object):
2307+
"""
2308+
Convert a list of tuples into an object array. Any subclass of
2309+
tuple in `rows` will be casted to tuple.
2310+
2311+
Parameters
2312+
----------
2313+
rows : 2-d array (N, K)
2314+
A list of tuples to be converted into an array.
2315+
2316+
Returns
2317+
-------
2318+
obj_array : numpy array of the object dtype
2319+
"""
23082320
cdef:
23092321
Py_ssize_t i, j, n, k, tmp
23102322
ndarray[object, ndim=2] result
23112323
tuple row
23122324

2325+
rows = list(rows)
23132326
n = len(rows)
23142327

23152328
k = 0

pandas/tests/frame/test_constructors.py

+16-2
Original file line numberDiff line numberDiff line change
@@ -1209,12 +1209,26 @@ def test_constructor_mixed_type_rows(self):
12091209
expected = DataFrame([[1, 2], [3, 4]])
12101210
tm.assert_frame_equal(result, expected)
12111211

1212-
def test_constructor_tuples(self):
1212+
@pytest.mark.parametrize("tuples,lists", [
1213+
((), []),
1214+
((()), []),
1215+
(((), ()), [(), ()]),
1216+
(((), ()), [[], []]),
1217+
(([], []), [[], []]),
1218+
(([1, 2, 3], [4, 5, 6]), [[1, 2, 3], [4, 5, 6]])
1219+
])
1220+
def test_constructor_tuple(self, tuples, lists):
1221+
# GH 25691
1222+
result = DataFrame(tuples)
1223+
expected = DataFrame(lists)
1224+
tm.assert_frame_equal(result, expected)
1225+
1226+
def test_constructor_list_of_tuples(self):
12131227
result = DataFrame({'A': [(1, 2), (3, 4)]})
12141228
expected = DataFrame({'A': Series([(1, 2), (3, 4)])})
12151229
tm.assert_frame_equal(result, expected)
12161230

1217-
def test_constructor_namedtuples(self):
1231+
def test_constructor_list_of_namedtuples(self):
12181232
# GH11181
12191233
from collections import namedtuple
12201234
named_tuple = namedtuple("Pandas", list('ab'))

0 commit comments

Comments
 (0)