def map_alleles(self, mapping, copy=True):
        """Transform alleles via a mapping.

        Parameters
        ----------
        mapping : ndarray, int8, shape (n_variants, max_allele)
            An array defining the allele mapping for each variant.
        copy : bool, optional
            If True, return a new array; if False, apply mapping in place
            (only applies for arrays with dtype int8; all other dtypes
            require a copy).

        Returns
        -------
        gm : GenotypeArray

        Examples
        --------

        >>> import allel
        >>> import numpy as np
        >>> g = allel.GenotypeArray([[[0, 0], [0, 1]],
        ...                          [[0, 2], [1, 1]],
        ...                          [[1, 2], [2, 1]],
        ...                          [[2, 2], [-1, -1]]], dtype='i1')
        >>> mapping = np.array([[1, 2, 0],
        ...                     [2, 0, 1],
        ...                     [2, 1, 0],
        ...                     [0, 2, 1]], dtype='i1')
        >>> g.map_alleles(mapping)
        <GenotypeArray shape=(4, 2, 2) dtype=int8>
        1/1 1/2
        2/1 0/0
        1/0 0/1
        1/1 ./.
        >>> v = g[:, 0]
        >>> v
        <GenotypeVector shape=(4, 2) dtype=int8>
        0/0 0/2 1/2 2/2
        >>> v.map_alleles(mapping)
        <GenotypeVector shape=(4, 2) dtype=int8>
        1/1 2/1 1/0 1/1

        Notes
        -----
        If a mask has been set, it is ignored by this function.

        For arrays with dtype int8 an optimised implementation is used which is
        faster and uses far less memory. It is recommended to convert arrays to
        dtype int8 where possible before calling this method.

        See Also
        --------
        create_allele_mapping

        """

        h = self.to_haplotypes()
        hm = h.map_alleles(mapping, copy=copy)
        if self.ndim == 2:
            gm = GenotypeVector(hm)
        else:
            gm = hm.to_genotypes(ploidy=self.ploidy)
        return gm
Transform alleles via a mapping.

        Parameters
        ----------
        mapping : ndarray, int8, shape (n_variants, max_allele)
            An array defining the allele mapping for each variant.
        copy : bool, optional
            If True, return a new array; if False, apply mapping in place
            (only applies for arrays with dtype int8; all other dtypes
            require a copy).

        Returns
        -------
        gm : GenotypeArray

        Examples
        --------

        >>> import allel
        >>> import numpy as np
        >>> g = allel.GenotypeArray([[[0, 0], [0, 1]],
        ...                          [[0, 2], [1, 1]],
        ...                          [[1, 2], [2, 1]],
        ...                          [[2, 2], [-1, -1]]], dtype='i1')
        >>> mapping = np.array([[1, 2, 0],
        ...                     [2, 0, 1],
        ...                     [2, 1, 0],
        ...                     [0, 2, 1]], dtype='i1')
        >>> g.map_alleles(mapping)
        <GenotypeArray shape=(4, 2, 2) dtype=int8>
        1/1 1/2
        2/1 0/0
        1/0 0/1
        1/1 ./.
        >>> v = g[:, 0]
        >>> v
        <GenotypeVector shape=(4, 2) dtype=int8>
        0/0 0/2 1/2 2/2
        >>> v.map_alleles(mapping)
        <GenotypeVector shape=(4, 2) dtype=int8>
        1/1 2/1 1/0 1/1

        Notes
        -----
        If a mask has been set, it is ignored by this function.

        For arrays with dtype int8 an optimised implementation is used which is
        faster and uses far less memory. It is recommended to convert arrays to
        dtype int8 where possible before calling this method.

        See Also
        --------
        create_allele_mapping