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