@@ -1673,66 +1673,14 @@ def _setitem_with_indexer(self, indexer, value):
1673
1673
1674
1674
# we have an equal len Frame
1675
1675
if isinstance (value , ABCDataFrame ):
1676
- sub_indexer = list (indexer )
1677
- multiindex_indexer = isinstance (labels , ABCMultiIndex )
1678
- # TODO: we are implicitly assuming value.columns is unique
1679
- unique_cols = value .columns .is_unique
1680
-
1681
- if not unique_cols and value .columns .equals (self .obj .columns ):
1682
- # We assume we are already aligned, see
1683
- # test_iloc_setitem_frame_duplicate_columns_multiple_blocks
1684
- for loc in ilocs :
1685
- item = item_labels [loc ]
1686
- if item in value :
1687
- sub_indexer [info_axis ] = item
1688
- v = self ._align_series (
1689
- tuple (sub_indexer ),
1690
- value .iloc [:, loc ],
1691
- multiindex_indexer ,
1692
- )
1693
- else :
1694
- v = np .nan
1695
-
1696
- self ._setitem_single_column (loc , v , plane_indexer )
1697
-
1698
- elif not unique_cols :
1699
- raise ValueError (
1700
- "Setting with non-unique columns is not allowed."
1701
- )
1702
-
1703
- else :
1704
- for loc in ilocs :
1705
- item = item_labels [loc ]
1706
- if item in value :
1707
- sub_indexer [info_axis ] = item
1708
- v = self ._align_series (
1709
- tuple (sub_indexer ), value [item ], multiindex_indexer
1710
- )
1711
- else :
1712
- v = np .nan
1713
-
1714
- self ._setitem_single_column (loc , v , plane_indexer )
1676
+ self ._setitem_with_indexer_frame_value (indexer , value )
1715
1677
1716
1678
# we have an equal len ndarray/convertible to our labels
1717
1679
# hasattr first, to avoid coercing to ndarray without reason.
1718
1680
# But we may be relying on the ndarray coercion to check ndim.
1719
1681
# Why not just convert to an ndarray earlier on if needed?
1720
1682
elif np .ndim (value ) == 2 :
1721
-
1722
- # note that this coerces the dtype if we are mixed
1723
- # GH 7551
1724
- value = np .array (value , dtype = object )
1725
- if len (ilocs ) != value .shape [1 ]:
1726
- raise ValueError (
1727
- "Must have equal len keys and value "
1728
- "when setting with an ndarray"
1729
- )
1730
-
1731
- for i , loc in enumerate (ilocs ):
1732
- # setting with a list, re-coerces
1733
- self ._setitem_single_column (
1734
- loc , value [:, i ].tolist (), plane_indexer
1735
- )
1683
+ self ._setitem_with_indexer_2d_value (indexer , value )
1736
1684
1737
1685
elif (
1738
1686
len (labels ) == 1
@@ -1766,6 +1714,67 @@ def _setitem_with_indexer(self, indexer, value):
1766
1714
else :
1767
1715
self ._setitem_single_block (indexer , value )
1768
1716
1717
+ def _setitem_with_indexer_2d_value (self , indexer , value ):
1718
+ # We get here with np.ndim(value) == 2, excluding DataFrame,
1719
+ # which goes through _setitem_with_indexer_frame_value
1720
+ plane_indexer = indexer [:1 ]
1721
+
1722
+ ilocs = self ._ensure_iterable_column_indexer (indexer [1 ])
1723
+
1724
+ # GH#7551 Note that this coerces the dtype if we are mixed
1725
+ value = np .array (value , dtype = object )
1726
+ if len (ilocs ) != value .shape [1 ]:
1727
+ raise ValueError (
1728
+ "Must have equal len keys and value when setting with an ndarray"
1729
+ )
1730
+
1731
+ for i , loc in enumerate (ilocs ):
1732
+ # setting with a list, re-coerces
1733
+ self ._setitem_single_column (loc , value [:, i ].tolist (), plane_indexer )
1734
+
1735
+ def _setitem_with_indexer_frame_value (self , indexer , value : "DataFrame" ):
1736
+ ilocs = self ._ensure_iterable_column_indexer (indexer [1 ])
1737
+
1738
+ sub_indexer = list (indexer )
1739
+ plane_indexer = indexer [:1 ]
1740
+
1741
+ multiindex_indexer = isinstance (self .obj .columns , ABCMultiIndex )
1742
+
1743
+ unique_cols = value .columns .is_unique
1744
+
1745
+ if not unique_cols and value .columns .equals (self .obj .columns ):
1746
+ # We assume we are already aligned, see
1747
+ # test_iloc_setitem_frame_duplicate_columns_multiple_blocks
1748
+ for loc in ilocs :
1749
+ item = self .obj .columns [loc ]
1750
+ if item in value :
1751
+ sub_indexer [1 ] = item
1752
+ val = self ._align_series (
1753
+ tuple (sub_indexer ),
1754
+ value .iloc [:, loc ],
1755
+ multiindex_indexer ,
1756
+ )
1757
+ else :
1758
+ val = np .nan
1759
+
1760
+ self ._setitem_single_column (loc , val , plane_indexer )
1761
+
1762
+ elif not unique_cols :
1763
+ raise ValueError ("Setting with non-unique columns is not allowed." )
1764
+
1765
+ else :
1766
+ for loc in ilocs :
1767
+ item = self .obj .columns [loc ]
1768
+ if item in value :
1769
+ sub_indexer [1 ] = item
1770
+ val = self ._align_series (
1771
+ tuple (sub_indexer ), value [item ], multiindex_indexer
1772
+ )
1773
+ else :
1774
+ val = np .nan
1775
+
1776
+ self ._setitem_single_column (loc , val , plane_indexer )
1777
+
1769
1778
def _setitem_single_column (self , loc : int , value , plane_indexer ):
1770
1779
# positional setting on column loc
1771
1780
pi = plane_indexer
0 commit comments