@@ -1245,7 +1245,10 @@ def value_getitem(placement):
1245
1245
self ._known_consolidated = False
1246
1246
1247
1247
def _iset_split_block (
1248
- self , blkno_l : int , blk_locs : np .ndarray , value : ArrayLike | None = None
1248
+ self ,
1249
+ blkno_l : int ,
1250
+ blk_locs : np .ndarray | list [int ],
1251
+ value : ArrayLike | None = None ,
1249
1252
) -> None :
1250
1253
"""Removes columns from a block by splitting the block.
1251
1254
@@ -1266,12 +1269,8 @@ def _iset_split_block(
1266
1269
1267
1270
nbs_tup = tuple (blk .delete (blk_locs ))
1268
1271
if value is not None :
1269
- # Argument 1 to "BlockPlacement" has incompatible type "BlockPlacement";
1270
- # expected "Union[int, slice, ndarray[Any, Any]]"
1271
- first_nb = new_block_2d (
1272
- value ,
1273
- BlockPlacement (blk .mgr_locs [blk_locs ]), # type: ignore[arg-type]
1274
- )
1272
+ locs = blk .mgr_locs .as_array [blk_locs ]
1273
+ first_nb = new_block_2d (value , BlockPlacement (locs ))
1275
1274
else :
1276
1275
first_nb = nbs_tup [0 ]
1277
1276
nbs_tup = tuple (nbs_tup [1 :])
@@ -1282,6 +1281,10 @@ def _iset_split_block(
1282
1281
)
1283
1282
self .blocks = blocks_tup
1284
1283
1284
+ if not nbs_tup and value is not None :
1285
+ # No need to update anything if split did not happen
1286
+ return
1287
+
1285
1288
self ._blklocs [first_nb .mgr_locs .indexer ] = np .arange (len (first_nb ))
1286
1289
1287
1290
for i , nb in enumerate (nbs_tup ):
@@ -1325,11 +1328,18 @@ def column_setitem(
1325
1328
intermediate Series at the DataFrame level (`s = df[loc]; s[idx] = value`)
1326
1329
"""
1327
1330
if using_copy_on_write () and not self ._has_no_reference (loc ):
1328
- # otherwise perform Copy-on-Write and clear the reference
1329
1331
blkno = self .blknos [loc ]
1330
- blocks = list (self .blocks )
1331
- blocks [blkno ] = blocks [blkno ].copy ()
1332
- self .blocks = tuple (blocks )
1332
+ # Split blocks to only copy the column we want to modify
1333
+ blk_loc = self .blklocs [loc ]
1334
+ # Copy our values
1335
+ values = self .blocks [blkno ].values
1336
+ if values .ndim == 1 :
1337
+ values = values .copy ()
1338
+ else :
1339
+ # Use [blk_loc] as indexer to keep ndim=2, this already results in a
1340
+ # copy
1341
+ values = values [[blk_loc ]]
1342
+ self ._iset_split_block (blkno , [blk_loc ], values )
1333
1343
1334
1344
# this manager is only created temporarily to mutate the values in place
1335
1345
# so don't track references, otherwise the `setitem` would perform CoW again
0 commit comments