def weighted_sample(
    sample_collection,
    k,
    weights,
    tag=None,
    exact=True,
    seed=None,
):
    """Generates a random sample of size ``k`` from the given collection such
    that the probability of selecting each sample is proportional to the given
    per-sample weights.

    Example::

        import fiftyone as fo
        import fiftyone.utils.random as four
        import fiftyone.zoo as foz
        from fiftyone import ViewField as F

        dataset = foz.load_zoo_dataset("cifar10", split="train")

        # Sample proportional to label length
        weights = dataset.values(F("ground_truth.label").strlen())
        sample = four.weighted_sample(dataset, 10000, weights)

        # Plot results
        plot = fo.CategoricalHistogram(
            "ground_truth.label",
            order=lambda kv: -len(kv[0]),  # order by label length
            init_view=sample,
        )
        plot.show()

    Args:
        sample_collection: a :class:`fiftyone.core.collections.SampleCollection`
        k: the number of samples to select
        weights: an array of per-sample weights
        tag (None): an optional sample tag to use to encode the results
        exact (True): whether to tag exactly ``k`` samples (True) or sample so
            that the expected number of samples is ``k`` (False)
        seed (None): an optional random seed to use

    Returns:
        a :class:`fiftyone.core.view.DatasetView` containing the sample
    """
    weights = np.asarray(weights)
    probs = (k / sum(weights)) * weights

    rs = np.random.RandomState(seed=seed)  # pylint: disable=no-member
    rands = rs.rand(len(sample_collection))

    if exact:
        inds = np.argpartition(rands - probs, k)[:k]
    else:
        inds = rands < probs

    ids = np.array(sample_collection.values("id"))
    select_ids = ids[inds]

    view = sample_collection[select_ids]

    if tag is not None:
        view.tag_samples(tag)
        view = sample_collection.match_tags(tag)

    return view
Generates a random sample of size ``k`` from the given collection such
    that the probability of selecting each sample is proportional to the given
    per-sample weights.

    Example::

        import fiftyone as fo
        import fiftyone.utils.random as four
        import fiftyone.zoo as foz
        from fiftyone import ViewField as F

        dataset = foz.load_zoo_dataset("cifar10", split="train")

        # Sample proportional to label length
        weights = dataset.values(F("ground_truth.label").strlen())
        sample = four.weighted_sample(dataset, 10000, weights)

        # Plot results
        plot = fo.CategoricalHistogram(
            "ground_truth.label",
            order=lambda kv: -len(kv[0]),  # order by label length
            init_view=sample,
        )
        plot.show()

    Args:
        sample_collection: a :class:`fiftyone.core.collections.SampleCollection`
        k: the number of samples to select
        weights: an array of per-sample weights
        tag (None): an optional sample tag to use to encode the results
        exact (True): whether to tag exactly ``k`` samples (True) or sample so
            that the expected number of samples is ``k`` (False)
        seed (None): an optional random seed to use

    Returns:
        a :class:`fiftyone.core.view.DatasetView` containing the sample
    
fiftyone/utils/random.py