Skip to content

Commit 2a8f11f

Browse files
committed
add in split_and_operate
1 parent af99124 commit 2a8f11f

File tree

1 file changed

+72
-6
lines changed

1 file changed

+72
-6
lines changed

pandas/core/internals.py

Lines changed: 72 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -397,12 +397,75 @@ def fillna(self, value, limit=None, inplace=False, downcast=None,
397397
if not mask.any():
398398
return self if inplace else self.copy()
399399

400-
# try again with a compatible block
401-
block = self.coerce_to_target_dtype(original_value)
402-
return block.fillna(original_value,
403-
limit=limit,
404-
inplace=inplace,
405-
downcast=False)
400+
# operate column-by-column
401+
def f(m, v):
402+
403+
# try again with a compatible block
404+
block = self.coerce_to_target_dtype(original_value)
405+
return block.fillna(original_value,
406+
limit=limit,
407+
inplace=inplace,
408+
downcast=False)
409+
410+
return self.split_and_operate(mask, f, inplace)
411+
412+
def split_and_operate(self, mask, f, inplace):
413+
"""
414+
split the block per-column. if masking
415+
that block, promot if needed, then
416+
apply the function f
417+
418+
Parameters
419+
----------
420+
mask : 2-d boolean mask
421+
f : function accepting (1-mask, 1-d values)
422+
inplace : boolean
423+
424+
Returns
425+
-------
426+
list of blocks
427+
"""
428+
429+
new_values = self.values
430+
431+
def make_a_block(nv, ref_loc):
432+
if isinstance(nv, Block):
433+
block = nv
434+
elif isinstance(nv, list):
435+
block = nv[0]
436+
else:
437+
# Put back the dimension that was taken from it and make
438+
# a block out of the result.
439+
block = self.make_block(values=nv[np.newaxis],
440+
placement=[ref_loc], fastpath=True)
441+
return block
442+
443+
# ndim == 1
444+
if self.ndim == 1:
445+
446+
if mask.any():
447+
nv = f(mask, new_values)
448+
else:
449+
nv = new_values if inplace else new_values.copy()
450+
block = make_a_block(nv, 0)
451+
return block
452+
453+
# ndim > 1
454+
new_blocks = []
455+
for i, ref_loc in enumerate(self.mgr_locs):
456+
m = mask[i]
457+
v = new_values[i]
458+
459+
# need a new block
460+
if m.any():
461+
nv = f(m, v)
462+
else:
463+
nv = v if inplace else v.copy()
464+
465+
block = make_a_block(nv, ref_loc)
466+
new_blocks.append(block)
467+
468+
return new_blocks
406469

407470
def _maybe_downcast(self, blocks, downcast=None):
408471

@@ -899,6 +962,9 @@ def putmask(self, mask, new, align=True, inplace=False, axis=0,
899962
new_shape.insert(axis, 1)
900963
new = new.reshape(tuple(new_shape))
901964

965+
# TODO(jreback)
966+
# use split_and_operate
967+
902968
# need to go column by column
903969
new_blocks = []
904970
if self.ndim > 1:

0 commit comments

Comments
 (0)