@@ -681,7 +681,7 @@ def __setitem__(self, key, value):
681681 self ._has_valid_setitem_indexer (key )
682682
683683 iloc = self if self .name == "iloc" else self .obj .iloc
684- iloc ._setitem_with_indexer (indexer , value )
684+ iloc ._setitem_with_indexer (indexer , value , self . name )
685685
686686 def _validate_key (self , key , axis : int ):
687687 """
@@ -1517,7 +1517,7 @@ def _get_setitem_indexer(self, key):
15171517
15181518 # -------------------------------------------------------------------
15191519
1520- def _setitem_with_indexer (self , indexer , value ):
1520+ def _setitem_with_indexer (self , indexer , value , name = "iloc" ):
15211521 """
15221522 _setitem_with_indexer is for setting values on a Series/DataFrame
15231523 using positional indexers.
@@ -1593,7 +1593,7 @@ def _setitem_with_indexer(self, indexer, value):
15931593 new_indexer = convert_from_missing_indexer_tuple (
15941594 indexer , self .obj .axes
15951595 )
1596- self ._setitem_with_indexer (new_indexer , value )
1596+ self ._setitem_with_indexer (new_indexer , value , name )
15971597
15981598 return
15991599
@@ -1624,11 +1624,11 @@ def _setitem_with_indexer(self, indexer, value):
16241624 # align and set the values
16251625 if take_split_path :
16261626 # We have to operate column-wise
1627- self ._setitem_with_indexer_split_path (indexer , value )
1627+ self ._setitem_with_indexer_split_path (indexer , value , name )
16281628 else :
1629- self ._setitem_single_block (indexer , value )
1629+ self ._setitem_single_block (indexer , value , name )
16301630
1631- def _setitem_with_indexer_split_path (self , indexer , value ):
1631+ def _setitem_with_indexer_split_path (self , indexer , value , name : str ):
16321632 """
16331633 Setitem column-wise.
16341634 """
@@ -1642,7 +1642,7 @@ def _setitem_with_indexer_split_path(self, indexer, value):
16421642 if isinstance (indexer [0 ], np .ndarray ) and indexer [0 ].ndim > 2 :
16431643 raise ValueError (r"Cannot set values with ndim > 2" )
16441644
1645- if isinstance (value , ABCSeries ):
1645+ if isinstance (value , ABCSeries ) and name != "iloc" :
16461646 value = self ._align_series (indexer , value )
16471647
16481648 # Ensure we have something we can iterate over
@@ -1657,7 +1657,7 @@ def _setitem_with_indexer_split_path(self, indexer, value):
16571657 if is_list_like_indexer (value ) and getattr (value , "ndim" , 1 ) > 0 :
16581658
16591659 if isinstance (value , ABCDataFrame ):
1660- self ._setitem_with_indexer_frame_value (indexer , value )
1660+ self ._setitem_with_indexer_frame_value (indexer , value , name )
16611661
16621662 elif np .ndim (value ) == 2 :
16631663 self ._setitem_with_indexer_2d_value (indexer , value )
@@ -1714,7 +1714,7 @@ def _setitem_with_indexer_2d_value(self, indexer, value):
17141714 # setting with a list, re-coerces
17151715 self ._setitem_single_column (loc , value [:, i ].tolist (), pi )
17161716
1717- def _setitem_with_indexer_frame_value (self , indexer , value : "DataFrame" ):
1717+ def _setitem_with_indexer_frame_value (self , indexer , value : "DataFrame" , name : str ):
17181718 ilocs = self ._ensure_iterable_column_indexer (indexer [1 ])
17191719
17201720 sub_indexer = list (indexer )
@@ -1724,7 +1724,13 @@ def _setitem_with_indexer_frame_value(self, indexer, value: "DataFrame"):
17241724
17251725 unique_cols = value .columns .is_unique
17261726
1727- if not unique_cols and value .columns .equals (self .obj .columns ):
1727+ # We do not want to align the value in case of iloc GH#37728
1728+ if name == "iloc" :
1729+ for i , loc in enumerate (ilocs ):
1730+ val = value .iloc [:, i ]
1731+ self ._setitem_single_column (loc , val , pi )
1732+
1733+ elif not unique_cols and value .columns .equals (self .obj .columns ):
17281734 # We assume we are already aligned, see
17291735 # test_iloc_setitem_frame_duplicate_columns_multiple_blocks
17301736 for loc in ilocs :
@@ -1787,7 +1793,7 @@ def _setitem_single_column(self, loc: int, value, plane_indexer):
17871793 # reset the sliced object if unique
17881794 self .obj ._iset_item (loc , ser )
17891795
1790- def _setitem_single_block (self , indexer , value ):
1796+ def _setitem_single_block (self , indexer , value , name : str ):
17911797 """
17921798 _setitem_with_indexer for the case when we have a single Block.
17931799 """
@@ -1815,14 +1821,13 @@ def _setitem_single_block(self, indexer, value):
18151821 return
18161822
18171823 indexer = maybe_convert_ix (* indexer )
1818-
1819- if isinstance (value , (ABCSeries , dict )):
1824+ if isinstance (value , ABCSeries ) and name != "iloc" or isinstance (value , dict ):
18201825 # TODO(EA): ExtensionBlock.setitem this causes issues with
18211826 # setting for extensionarrays that store dicts. Need to decide
18221827 # if it's worth supporting that.
18231828 value = self ._align_series (indexer , Series (value ))
18241829
1825- elif isinstance (value , ABCDataFrame ):
1830+ elif isinstance (value , ABCDataFrame ) and name != "iloc" :
18261831 value = self ._align_frame (indexer , value )
18271832
18281833 # check for chained assignment
@@ -1854,7 +1859,7 @@ def _setitem_with_indexer_missing(self, indexer, value):
18541859 if index .is_unique :
18551860 new_indexer = index .get_indexer ([new_index [- 1 ]])
18561861 if (new_indexer != - 1 ).any ():
1857- return self ._setitem_with_indexer (new_indexer , value )
1862+ return self ._setitem_with_indexer (new_indexer , value , "loc" )
18581863
18591864 # this preserves dtype of the value
18601865 new_values = Series ([value ])._values
0 commit comments