def split_and_operate(self, mask, f, inplace):
if mask is None:<EOL><INDENT>mask = np.ones(self.shape, dtype=bool)<EOL><DEDENT>new_values = self.values<EOL>def make_a_block(nv, ref_loc):<EOL><INDENT>if isinstance(nv, Block):<EOL><INDENT>block = nv<EOL><DEDENT>elif isinstance(nv, list):<EOL><INDENT>block = nv[<NUM_LIT:0>]<EOL><DEDENT>else:<EOL><INDENT>try:<EOL><INDENT>nv = _block_shape(nv, ndim=self.ndim)<EOL><DEDENT>except (AttributeError, NotImplementedError):<EOL><INDENT>pass<EOL><DEDENT>block = self.make_block(values=nv,<EOL>placement=ref_loc)<EOL><DEDENT>return block<EOL><DEDENT>if self.ndim == <NUM_LIT:1>:<EOL><INDENT>if mask.any():<EOL><INDENT>nv = f(mask, new_values, None)<EOL><DEDENT>else:<EOL><INDENT>nv = new_values if inplace else new_values.copy()<EOL><DEDENT>block = make_a_block(nv, self.mgr_locs)<EOL>return [block]<EOL><DEDENT>new_blocks = []<EOL>for i, ref_loc in enumerate(self.mgr_locs):<EOL><INDENT>m = mask[i]<EOL>v = new_values[i]<EOL>if m.any():<EOL><INDENT>nv = f(m, v, i)<EOL><DEDENT>else:<EOL><INDENT>nv = v if inplace else v.copy()<EOL><DEDENT>block = make_a_block(nv, [ref_loc])<EOL>new_blocks.append(block)<EOL><DEDENT>return new_blocks<EOL>
split the block per-column, and apply the callable f
per-column, return a new block for each. Handle
masking which will not change a block unless needed.

Parameters
----------
mask : 2-d boolean mask
f : callable accepting (1d-mask, 1d values, indexer)
inplace : boolean

Returns
-------
list of blocks