def filter_for_probability(key: str, population: Union[pd.DataFrame, pd.Series, Index],
                           probability: Array, index_map: IndexMap=None) -> Union[pd.DataFrame, pd.Series, Index]:
    """Decide an event outcome for each individual in a population from probabilities.

    Given a population or its index and an array of associated probabilities
    for some event to happen, we create and return the sub-population for whom
    the event occurred.

    Parameters
    ----------
    key :
        A string used to create a seed for the random number generation.
    population :
        A view on the simulants for which we are determining the
        outcome of an event.
    probability :
        A 1d list of probabilities of the event under consideration
        occurring which corresponds (i.e. `len(population) == len(probability)`)
        to the population array passed in.
    index_map :
        A mapping between the provided index (which may contain ints, floats,
        datetimes or any arbitrary combination of them) and an integer index
        into the random number array.

    Returns
    -------
    pd.core.generic.PandasObject
        The sub-population of the simulants for whom the event occurred.
        The return type will be the same as type(population)
    """
    if population.empty:
        return population

    index = population if isinstance(population, pd.Index) else population.index
    draw = random(key, index, index_map)
    mask = np.array(draw < probability)
    return population[mask]