@@ -398,7 +398,7 @@ def fillna(self, value, limit=None, inplace=False, downcast=None,
398
398
return self if inplace else self .copy ()
399
399
400
400
# operate column-by-column
401
- def f (m , v ):
401
+ def f (m , v , i ):
402
402
403
403
# try again with a compatible block
404
404
block = self .coerce_to_target_dtype (original_value )
@@ -411,14 +411,14 @@ def f(m, v):
411
411
412
412
def split_and_operate (self , mask , f , inplace ):
413
413
"""
414
- split the block per-column. if masking
415
- that block, promot if needed, then
416
- apply the function f
414
+ split the block per-column, and apply the callable f
415
+ per-column, return a new block for each. Handle
416
+ masking which will not change a block unless needed.
417
417
418
418
Parameters
419
419
----------
420
420
mask : 2-d boolean mask
421
- f : function accepting (1 -mask, 1-d values)
421
+ f : callable accepting (1d -mask, 1d values, indexer )
422
422
inplace : boolean
423
423
424
424
Returns
@@ -436,19 +436,19 @@ def make_a_block(nv, ref_loc):
436
436
else :
437
437
# Put back the dimension that was taken from it and make
438
438
# a block out of the result.
439
- block = self .make_block (values = nv [np .newaxis ],
440
- placement = [ref_loc ], fastpath = True )
439
+ nv = _block_shape (nv , ndim = self .ndim )
440
+ block = self .make_block (values = nv ,
441
+ placement = ref_loc , fastpath = True )
441
442
return block
442
443
443
444
# ndim == 1
444
445
if self .ndim == 1 :
445
-
446
446
if mask .any ():
447
- nv = f (mask , new_values )
447
+ nv = f (mask , new_values , None )
448
448
else :
449
449
nv = new_values if inplace else new_values .copy ()
450
- block = make_a_block (nv , 0 )
451
- return block
450
+ block = make_a_block (nv , self . mgr_locs )
451
+ return [ block ]
452
452
453
453
# ndim > 1
454
454
new_blocks = []
@@ -458,11 +458,11 @@ def make_a_block(nv, ref_loc):
458
458
459
459
# need a new block
460
460
if m .any ():
461
- nv = f (m , v )
461
+ nv = f (m , v , i )
462
462
else :
463
463
nv = v if inplace else v .copy ()
464
464
465
- block = make_a_block (nv , ref_loc )
465
+ block = make_a_block (nv , [ ref_loc ] )
466
466
new_blocks .append (block )
467
467
468
468
return new_blocks
@@ -960,44 +960,31 @@ def putmask(self, mask, new, align=True, inplace=False, axis=0,
960
960
new_shape .insert (axis , 1 )
961
961
new = new .reshape (tuple (new_shape ))
962
962
963
- # TODO(jreback)
964
- # use split_and_operate
965
-
966
- # need to go column by column
967
- new_blocks = []
968
- if self .ndim > 1 :
969
- for i , ref_loc in enumerate (self .mgr_locs ):
970
- m = mask [i ]
971
- v = new_values [i ]
972
-
973
- # need a new block
974
- if m .any ():
975
- if isinstance (new , np .ndarray ):
976
- n = np .squeeze (new [i % new .shape [0 ]])
977
- else :
978
- n = np .array (new )
979
-
980
- # type of the new block
981
- dtype , _ = maybe_promote (n .dtype )
963
+ # operate column-by-column
964
+ def f (m , v , i ):
982
965
983
- # we need to explicitly astype here to make a copy
984
- n = n . astype ( dtype )
966
+ # TODO(jreback)
967
+ # see if we can use coerce_to_target_dtype here instead
985
968
986
- nv = _putmask_smart (v , m , n )
969
+ if i is None :
970
+ # ndim==1 case.
971
+ n = new
972
+ else :
973
+ if isinstance (new , np .ndarray ):
974
+ n = np .squeeze (new [i % new .shape [0 ]])
987
975
else :
988
- nv = v if inplace else v . copy ( )
976
+ n = np . array ( new )
989
977
990
- # Put back the dimension that was taken from it and make
991
- # a block out of the result.
992
- block = self .make_block (values = nv [np .newaxis ],
993
- placement = [ref_loc ], fastpath = True )
978
+ # type of the new block
979
+ dtype , _ = maybe_promote (n .dtype )
994
980
995
- new_blocks .append (block )
981
+ # we need to explicitly astype here to make a copy
982
+ n = n .astype (dtype )
996
983
997
- else :
998
- nv = _putmask_smart (new_values , mask , new )
999
- new_blocks .append (self .make_block (values = nv , fastpath = True ))
984
+ nv = _putmask_smart (v , m , n )
985
+ return nv
1000
986
987
+ new_blocks = self .split_and_operate (mask , f , inplace )
1001
988
return new_blocks
1002
989
1003
990
if inplace :
0 commit comments