@@ -672,6 +672,7 @@ def test_from_arrays(self):
672
672
for lev , lab in zip (self .index .levels , self .index .labels ):
673
673
arrays .append (np .asarray (lev ).take (lab ))
674
674
675
+ # list of arrays as input
675
676
result = MultiIndex .from_arrays (arrays )
676
677
assert list (result ) == list (self .index )
677
678
@@ -681,6 +682,21 @@ def test_from_arrays(self):
681
682
assert result .levels [0 ].equals (Index ([Timestamp ('20130101' )]))
682
683
assert result .levels [1 ].equals (Index (['a' , 'b' ]))
683
684
685
+ def test_from_arrays_iterator (self ):
686
+ # GH 18434
687
+ arrays = []
688
+ for lev , lab in zip (self .index .levels , self .index .labels ):
689
+ arrays .append (np .asarray (lev ).take (lab ))
690
+
691
+ # iterator as input
692
+ result = MultiIndex .from_arrays (iter (arrays ))
693
+ assert list (result ) == list (self .index )
694
+
695
+ # invalid iterator input
696
+ with tm .assert_raises_regex (
697
+ TypeError , "Input must be a list / sequence of array-likes." ):
698
+ MultiIndex .from_arrays (0 )
699
+
684
700
def test_from_arrays_index_series_datetimetz (self ):
685
701
idx1 = pd .date_range ('2015-01-01 10:00' , freq = 'D' , periods = 3 ,
686
702
tz = 'US/Eastern' )
@@ -827,6 +843,26 @@ def test_from_product(self):
827
843
tm .assert_index_equal (result , expected )
828
844
assert result .names == names
829
845
846
+ def test_from_product_iterator (self ):
847
+ # GH 18434
848
+ first = ['foo' , 'bar' , 'buz' ]
849
+ second = ['a' , 'b' , 'c' ]
850
+ names = ['first' , 'second' ]
851
+ tuples = [('foo' , 'a' ), ('foo' , 'b' ), ('foo' , 'c' ), ('bar' , 'a' ),
852
+ ('bar' , 'b' ), ('bar' , 'c' ), ('buz' , 'a' ), ('buz' , 'b' ),
853
+ ('buz' , 'c' )]
854
+ expected = MultiIndex .from_tuples (tuples , names = names )
855
+
856
+ # iterator as input
857
+ result = MultiIndex .from_product (iter ([first , second ]), names = names )
858
+ assert result .equals (expected )
859
+ assert result .names == names
860
+
861
+ # Invalid non-iterable input
862
+ with tm .assert_raises_regex (
863
+ TypeError , "Input must be a list / sequence of iterables." ):
864
+ MultiIndex .from_product (0 )
865
+
830
866
def test_from_product_empty (self ):
831
867
# 0 levels
832
868
with tm .assert_raises_regex (
@@ -1725,8 +1761,30 @@ def test_from_tuples(self):
1725
1761
'from empty list' ,
1726
1762
MultiIndex .from_tuples , [])
1727
1763
1728
- idx = MultiIndex .from_tuples (((1 , 2 ), (3 , 4 )), names = ['a' , 'b' ])
1729
- assert len (idx ) == 2
1764
+ expected = MultiIndex (levels = [[1 , 3 ], [2 , 4 ]],
1765
+ labels = [[0 , 1 ], [0 , 1 ]],
1766
+ names = ['a' , 'b' ])
1767
+
1768
+ # input tuples
1769
+ result = MultiIndex .from_tuples (((1 , 2 ), (3 , 4 )), names = ['a' , 'b' ])
1770
+ assert expected .names == result .names
1771
+ assert result .equals (expected )
1772
+
1773
+ def test_from_tuples_iterator (self ):
1774
+ # GH 18434
1775
+ # input iterator for tuples
1776
+ expected = MultiIndex (levels = [[1 , 3 ], [2 , 4 ]],
1777
+ labels = [[0 , 1 ], [0 , 1 ]],
1778
+ names = ['a' , 'b' ])
1779
+
1780
+ result = MultiIndex .from_tuples (zip ([1 , 3 ], [2 , 4 ]), names = ['a' , 'b' ])
1781
+ assert expected .names == result .names
1782
+ assert result .equals (expected )
1783
+
1784
+ # input non-iterables
1785
+ with tm .assert_raises_regex (
1786
+ TypeError , 'Input must be a list / sequence of tuple-likes.' ):
1787
+ MultiIndex .from_tuples (0 )
1730
1788
1731
1789
def test_from_tuples_empty (self ):
1732
1790
# GH 16777
0 commit comments