Skip to content

Commit c2bbe5c

Browse files
committed
Fix #18434
MultiIndex.from_tuples/from_arrays/from_product accept iterators in python 3. Ensures compatibility between 2 and 3.
1 parent fedc503 commit c2bbe5c

File tree

3 files changed

+32
-2
lines changed

3 files changed

+32
-2
lines changed

doc/source/whatsnew/v0.22.0.txt

+1
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,7 @@ Indexing
137137
- Bug in :func:`Series.truncate` which raises ``TypeError`` with a monotonic ``PeriodIndex`` (:issue:`17717`)
138138
- Bug in :func:`DataFrame.groupby` where tuples were interpreted as lists of keys rather than as keys (:issue:`17979`, :issue:`18249`)
139139
- Bug in :func:`MultiIndex.remove_unused_levels`` which would fill nan values (:issue:`18417`)
140+
- Bug in :func:`MultiIndex.from_tuples`` which would fail to take zipped tuples in python3 (:issue:`18434`)
140141
-
141142

142143
I/O

pandas/core/indexes/multi.py

+15
Original file line numberDiff line numberDiff line change
@@ -1162,6 +1162,11 @@ def from_arrays(cls, arrays, sortorder=None, names=None):
11621162
MultiIndex.from_product : Make a MultiIndex from cartesian product
11631163
of iterables
11641164
"""
1165+
if not is_list_like(arrays):
1166+
raise TypeError("Inappropriate input for list of arrays.")
1167+
elif is_iterator(arrays):
1168+
arrays = list(arrays)
1169+
11651170
# Check if lengths of all arrays are equal or not,
11661171
# raise ValueError, if not
11671172
for i in range(1, len(arrays)):
@@ -1206,6 +1211,11 @@ def from_tuples(cls, tuples, sortorder=None, names=None):
12061211
MultiIndex.from_product : Make a MultiIndex from cartesian product
12071212
of iterables
12081213
"""
1214+
if not is_list_like(tuples):
1215+
raise TypeError('Inappropriate input for tuples.')
1216+
elif is_iterator(tuples):
1217+
tuples = list(tuples)
1218+
12091219
if len(tuples) == 0:
12101220
if names is None:
12111221
msg = 'Cannot infer number of levels from empty list'
@@ -1260,6 +1270,11 @@ def from_product(cls, iterables, sortorder=None, names=None):
12601270
from pandas.core.categorical import _factorize_from_iterables
12611271
from pandas.core.reshape.util import cartesian_product
12621272

1273+
if not is_list_like(iterables):
1274+
raise TypeError("Inappropriate input for iterables.")
1275+
elif is_iterator(iterables):
1276+
iterables = list(iterables)
1277+
12631278
labels, levels = _factorize_from_iterables(iterables)
12641279
labels = cartesian_product(labels)
12651280
return MultiIndex(levels, labels, sortorder=sortorder, names=names)

pandas/tests/indexes/test_multi.py

+16-2
Original file line numberDiff line numberDiff line change
@@ -674,6 +674,8 @@ def test_from_arrays(self):
674674

675675
result = MultiIndex.from_arrays(arrays)
676676
assert list(result) == list(self.index)
677+
result2 = MultiIndex.from_arrays(iter(arrays)) # iterator as input
678+
assert list(result2) == list(self.index)
677679

678680
# infer correctly
679681
result = MultiIndex.from_arrays([[pd.NaT, Timestamp('20130101')],
@@ -827,6 +829,11 @@ def test_from_product(self):
827829
tm.assert_index_equal(result, expected)
828830
assert result.names == names
829831

832+
# iterator as input
833+
result2 = MultiIndex.from_product(iter([first, second]), names=names)
834+
assert result2.equals(expected)
835+
assert result2.names == names
836+
830837
def test_from_product_empty(self):
831838
# 0 levels
832839
with tm.assert_raises_regex(
@@ -1725,8 +1732,15 @@ def test_from_tuples(self):
17251732
'from empty list',
17261733
MultiIndex.from_tuples, [])
17271734

1728-
idx = MultiIndex.from_tuples(((1, 2), (3, 4)), names=['a', 'b'])
1729-
assert len(idx) == 2
1735+
expected = MultiIndex(levels=[[1, 3], [2, 4]],
1736+
labels=[[0, 1], [0, 1]],
1737+
names=['a', 'b'])
1738+
res1 = MultiIndex.from_tuples(((1, 2), (3, 4)), names=['a', 'b'])
1739+
assert expected.names == res1.names
1740+
assert res1.equals(expected)
1741+
res2 = MultiIndex.from_tuples(zip([1, 3], [2, 4]), names=['a', 'b'])
1742+
assert expected.names == res2.names
1743+
assert res2.equals(expected)
17301744

17311745
def test_from_tuples_empty(self):
17321746
# GH 16777

0 commit comments

Comments
 (0)