@@ -659,24 +659,53 @@ def idelete(self, indexer):
659
659
660
660
def iset (self , loc : Union [int , slice , np .ndarray ], value ):
661
661
"""
662
- Set new item in-place. Does not consolidate. Adds new Block if not
663
- contained in the current set of items
662
+ Set new column(s).
663
+
664
+ This changes the ArrayManager in-place, but replaces (an) existing
665
+ column(s), not changing column values in-place).
666
+
667
+ Parameters
668
+ ----------
669
+ loc : integer, slice or boolean mask
670
+ Positional location (already bounds checked)
671
+ value : array-like
664
672
"""
673
+ # single column -> single integer index
665
674
if lib .is_integer (loc ):
666
- # TODO normalize array -> this should in theory not be needed?
675
+ # TODO the extract array should in theory not be needed?
667
676
value = extract_array (value , extract_numpy = True )
677
+
678
+ # TODO can we avoid needing to unpack this here? That means converting
679
+ # DataFrame into 1D array when loc is an integer
668
680
if isinstance (value , np .ndarray ) and value .ndim == 2 :
681
+ assert value .shape [1 ] == 1
669
682
value = value [0 , :]
670
683
671
684
assert isinstance (value , (np .ndarray , ExtensionArray ))
672
- # value = np.asarray(value)
673
- # assert isinstance(value, np.ndarray)
685
+ assert value .ndim == 1
674
686
assert len (value ) == len (self ._axes [0 ])
675
687
self .arrays [loc ] = value
676
688
return
677
689
678
- # TODO
679
- raise Exception
690
+ # multiple columns -> convert slice or array to integer indices
691
+ elif isinstance (loc , slice ):
692
+ indices = range (
693
+ loc .start if loc .start is not None else 0 ,
694
+ loc .stop if loc .stop is not None else self .shape_proper [1 ],
695
+ loc .step if loc .step is not None else 1 ,
696
+ )
697
+ else :
698
+ assert isinstance (loc , np .ndarray )
699
+ assert loc .dtype == "bool"
700
+ indices = np .nonzero (loc )[0 ]
701
+
702
+ assert value .ndim == 2
703
+ assert value .shape [0 ] == len (self ._axes [0 ])
704
+
705
+ for value_idx , mgr_idx in enumerate (indices ):
706
+ value_arr = value [:, value_idx ]
707
+ self .arrays [mgr_idx ] = value_arr
708
+ return
680
709
681
710
def insert (self , loc : int , item : Hashable , value , allow_duplicates : bool = False ):
682
711
"""
0 commit comments