Muestra aleatoria ponderada en python

Estoy buscando una definición razonable de una funciónweighted_sample eso no devuelve solo un índice aleatorio para una lista de pesos dados (que sería algo así como

def weighted_choice(weights, random=random):
    """ Given a list of weights [w_0, w_1, ..., w_n-1],
        return an index i in range(n) with probability proportional to w_i. """
    rnd = random.random() * sum(weights)
    for i, w in enumerate(weights):
        if w<0:
            raise ValueError("Negative weight encountered.")
        rnd -= w
        if rnd < 0:
            return i
    raise ValueError("Sum of weights is not positive")

para dar una distribución categórica con pesos constantes) pero una muestra aleatoria dek de aquellos,sin reemplazo, Tal comorandom.sample se comporta en comparación conrandom.choice.

Tal comoweighted_choice Se puede escribir como

lambda weights: random.choice([val for val, cnt in enumerate(weights)
    for i in range(cnt)])

weighted_sample podría ser escrito como

lambda weights, k: random.sample([val for val, cnt in enumerate(weights)
    for i in range(cnt)], k)

pero me gustaría una solución que no me obligue a desentrañar los pesos en una lista (posiblemente enorme).

Edición: si hay algoritmos agradables que me devuelvan un histograma / lista de frecuencias (en el mismo formato que el argumentoweights) en lugar de una secuencia de índices, eso también sería muy útil.

Respuestas a la pregunta(5)

Su respuesta a la pregunta