@@ -1633,14 +1633,12 @@ def _setitem_with_indexer(self, indexer, value):
16331633 info_idx = [info_idx ]
16341634 labels = item_labels [info_idx ]
16351635
1636+ plane_indexer = indexer [:1 ]
1637+ lplane_indexer = length_of_indexer (plane_indexer [0 ], self .obj .index )
1638+ # lplane_indexer gives the expected length of obj[indexer[0]]
1639+
16361640 if len (labels ) == 1 :
16371641 # We can operate on a single column
1638- item = labels [0 ]
1639- idx = indexer [0 ]
1640-
1641- plane_indexer = tuple ([idx ])
1642- lplane_indexer = length_of_indexer (plane_indexer [0 ], self .obj .index )
1643- # lplane_indexer gives the expected length of obj[idx]
16441642
16451643 # require that we are setting the right number of values that
16461644 # we are indexing
@@ -1652,11 +1650,6 @@ def _setitem_with_indexer(self, indexer, value):
16521650 "length than the value"
16531651 )
16541652
1655- # non-mi
1656- else :
1657- plane_indexer = indexer [:1 ]
1658- lplane_indexer = length_of_indexer (plane_indexer [0 ], self .obj .index )
1659-
16601653 def setter (item , v ):
16611654 ser = self .obj [item ]
16621655 pi = plane_indexer [0 ] if lplane_indexer == 1 else plane_indexer
@@ -1718,18 +1711,23 @@ def setter(item, v):
17181711
17191712 for i , item in enumerate (labels ):
17201713
1721- # setting with a list, recoerces
1714+ # setting with a list, re-coerces
17221715 setter (item , value [:, i ].tolist ())
17231716
1724- # we have an equal len list/ndarray
1725- elif _can_do_equal_len (
1726- labels , value , plane_indexer , lplane_indexer , self .obj
1717+ elif (
1718+ len (labels ) == 1
1719+ and lplane_indexer == len (value )
1720+ and not is_scalar (plane_indexer [0 ])
17271721 ):
1722+ # we have an equal len list/ndarray
17281723 setter (labels [0 ], value )
17291724
1730- # per label values
1731- else :
1725+ elif lplane_indexer == 0 and len (value ) == len (self .obj .index ):
1726+ # We get here in one case via .loc with a all-False mask
1727+ pass
17321728
1729+ else :
1730+ # per-label values
17331731 if len (labels ) != len (value ):
17341732 raise ValueError (
17351733 "Must have equal len keys and value "
@@ -1746,7 +1744,6 @@ def setter(item, v):
17461744
17471745 else :
17481746 if isinstance (indexer , tuple ):
1749- indexer = maybe_convert_ix (* indexer )
17501747
17511748 # if we are setting on the info axis ONLY
17521749 # set using those methods to avoid block-splitting
@@ -1764,6 +1761,8 @@ def setter(item, v):
17641761 self .obj [item_labels [indexer [info_axis ]]] = value
17651762 return
17661763
1764+ indexer = maybe_convert_ix (* indexer )
1765+
17671766 if isinstance (value , (ABCSeries , dict )):
17681767 # TODO(EA): ExtensionBlock.setitem this causes issues with
17691768 # setting for extensionarrays that store dicts. Need to decide
@@ -2277,26 +2276,3 @@ def _maybe_numeric_slice(df, slice_, include_bool=False):
22772276 dtypes .append (bool )
22782277 slice_ = IndexSlice [:, df .select_dtypes (include = dtypes ).columns ]
22792278 return slice_
2280-
2281-
2282- def _can_do_equal_len (labels , value , plane_indexer , lplane_indexer , obj ) -> bool :
2283- """
2284- Returns
2285- -------
2286- bool
2287- True if we have an equal len settable.
2288- """
2289- if not len (labels ) == 1 or not np .iterable (value ) or is_scalar (plane_indexer [0 ]):
2290- return False
2291-
2292- item = labels [0 ]
2293- index = obj [item ].index
2294-
2295- values_len = len (value )
2296- # equal len list/ndarray
2297- if len (index ) == values_len :
2298- return True
2299- elif lplane_indexer == values_len :
2300- return True
2301-
2302- return False
0 commit comments