ak.mask
-------

Defined in `awkward.operations.structure <https://github.com/scikit-hep/awkward-1.0/blob/80bbef0738a6b7928333d7c705ee1b359991de5b/src/awkward/operations/structure.py>`__ on `line 68 <https://github.com/scikit-hep/awkward-1.0/blob/80bbef0738a6b7928333d7c705ee1b359991de5b/src/awkward/operations/structure.py#L68>`__.

.. py:function:: ak.mask(array, mask, valid_when=True, highlevel=True, behavior=None)


    :param array: Data to mask, rather than filter.
    :param mask: The mask that overlays elements in the
             ``array`` with None. Must have the same length as ``array``.
    :type mask: array of booleans
    :param valid_when: If True, True values in ``mask`` are considered
                   valid (passed from ``array`` to the output); if False, False
                   values in ``mask`` are considered valid.
    :type valid_when: bool
    :param highlevel: If True, return an :py:obj:`ak.Array`; otherwise, return
                  a low-level :py:obj:`ak.layout.Content` subclass.
    :type highlevel: bool
    :param behavior: Custom :py:obj:`ak.behavior` for the output array, if
                 high-level.
    :type behavior: None or dict

Returns an array for which

.. code-block:: python


    output[i] = array[i] if mask[i] == valid_when else None

Unlike filtering data with :py:obj:`ak.Array.__getitem__`, this ``output`` has the
same length as the original ``array`` and can therefore be used in
calculations with it, such as
`universal functions <https://docs.scipy.org/doc/numpy/reference/ufuncs.html>`__.

For example, with an ``array`` like

.. code-block:: python


    ak.Array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])

with a boolean selection of ``good`` elements like

.. code-block:: python


    >>> good = (array % 2 == 1)
    >>> good
    <Array [False, True, False, ... False, True] type='10 * bool'>

could be used to filter the original ``array`` (or another with the same
length).

.. code-block:: python


    >>> array[good]
    <Array [1, 3, 5, 7, 9] type='5 * int64'>

However, this eliminates information about which elements were dropped and
where they were. If we instead use :py:obj:`ak.mask`,

.. code-block:: python


    >>> ak.mask(array, good)
    <Array [None, 1, None, 3, ... None, 7, None, 9] type='10 * ?int64'>

this information and the length of the array is preserved, and it can be
used in further calculations with the original ``array`` (or another with
the same length).

.. code-block:: python


    >>> ak.mask(array, good) + array
    <Array [None, 2, None, 6, ... 14, None, 18] type='10 * ?int64'>

In particular, successive filters can be applied to the same array.

Even if the ``array`` and/or the ``mask`` is nested,

.. code-block:: python


    >>> array = ak.Array([[[0, 1, 2], [], [3, 4], [5]], [[6, 7, 8], [9]]])
    >>> good = (array % 2 == 1)
    >>> good
    <Array [[[False, True, False], ... [True]]] type='2 * var * var * bool'>

it can still be used with :py:obj:`ak.mask` because the ``array`` and ``mask``
parameters are broadcasted.

.. code-block:: python


    >>> ak.mask(array, good)
    <Array [[[None, 1, None], ... None], [9]]] type='2 * var * var * ?int64'>

See :py:obj:`ak.broadcast_arrays` for details about broadcasting and the generalized
set of broadcasting rules.

Another syntax for

.. code-block:: python


    ak.mask(array, array_of_booleans)

is

.. code-block:: python


    array.mask[array_of_booleans]

(which is 5 characters away from simply filtering the ``array``).

