def mask_cmp_op(x, y, op, allowed_types):
<EOL>xrav = x.ravel()<EOL>result = np.empty(x.size, dtype=bool)<EOL>if isinstance(y, allowed_types):<EOL><INDENT>yrav = y.ravel()<EOL>mask = notna(xrav) & notna(yrav)<EOL>result[mask] = op(np.array(list(xrav[mask])),<EOL>np.array(list(yrav[mask])))<EOL><DEDENT>else:<EOL><INDENT>mask = notna(xrav)<EOL>result[mask] = op(np.array(list(xrav[mask])), y)<EOL><DEDENT>if op == operator.ne:  <EOL><INDENT>np.putmask(result, ~mask, True)<EOL><DEDENT>else:<EOL><INDENT>np.putmask(result, ~mask, False)<EOL><DEDENT>result = result.reshape(x.shape)<EOL>return result<EOL>
Apply the function `op` to only non-null points in x and y.

Parameters
----------
x : array-like
y : array-like
op : binary operation
allowed_types : class or tuple of classes

Returns
-------
result : ndarray[bool]