Create a join index by rearranging one index to match another

        Parameters
        ----------
        index: Index being rearranged
        other_index: Index used to supply values not found in index
        indexer: how to rearrange index
        how: replacement is only necessary if indexer based on other_index

        Returns
        -------
        join_index

def _create_join_index(self, index, other_index, indexer,
                           other_indexer, how='left'):
        """
        Create a join index by rearranging one index to match another

        Parameters
        ----------
        index: Index being rearranged
        other_index: Index used to supply values not found in index
        indexer: how to rearrange index
        how: replacement is only necessary if indexer based on other_index

        Returns
        -------
        join_index
        """
        join_index = index.take(indexer)
        if (self.how in (how, 'outer') and
                not isinstance(other_index, MultiIndex)):
            # if final index requires values in other_index but not target
            # index, indexer may hold missing (-1) values, causing Index.take
            # to take the final value in target index
            mask = indexer == -1
            if np.any(mask):
                # if values missing (-1) from target index,
                # take from other_index instead
                join_list = join_index.to_numpy()
                other_list = other_index.take(other_indexer).to_numpy()
                join_list[mask] = other_list[mask]
                join_index = Index(join_list, dtype=join_index.dtype,
                                   name=join_index.name)
        return join_index