Чернильный рисунок из урны

Я хочу запустить относительно простую случайную ничью в numpy, но я не могу найти хороший способ ее выразить. Я думаю, что лучший способ – описать его как рисунок из урны без замены. У меня есть урна с k цветами и шарами n_k каждого цвета. Я хочу нарисовать m шаров и узнать, сколько шаров каждого цвета у меня есть.

Моя текущая попытка

np.bincount(np.random.permutation(np.repeat(np.arange(k), n_k))[:m], minlength=k)

здесь n_k представляет собой массив длины k с n_k шаров.

Кажется, что это эквивалентно np.bincount(np.random.choice(k, m, n_k / n_k.sum(), minlength=k)

который немного лучше, но все же невелик.

2 Solutions collect form web for “Чернильный рисунок из урны”

Вы хотите реализовать многомерное гипергеометрическое распределение . Я не знаю ни одного из них, но он может уже существовать где-то там.

Вы можете реализовать его с помощью повторных вызовов numpy.random.hypergeometric . Будет ли это более эффективно, чем ваша реализация, зависит от количества цветов и количества шаров каждого цвета.

Например, вот сценарий, который печатает результат рисования из урны, содержащей три цвета (красный, зеленый и синий):

 from __future__ import print_function import numpy as np nred = 12 ngreen = 4 nblue = 18 m = 15 red = np.random.hypergeometric(nred, ngreen + nblue, m) green = np.random.hypergeometric(ngreen, nblue, m - red) blue = m - (red + green) print("red: %2i" % red) print("green: %2i" % green) print("blue: %2i" % blue) 

Пример вывода:

 red: 6 green: 1 blue: 8 

Следующая функция обобщает, что для выбора m шаров заданы colors массива, содержащие количество каждого цвета:

 def sample(m, colors): """ Parameters ---------- m : number balls to draw from the urn colors : one-dimensional array of number balls of each color in the urn Returns ------- One-dimensional array with the same length as `colors` containing the number of balls of each color in a random sample. """ remaining = np.cumsum(colors[::-1])[::-1] result = np.zeros(len(colors), dtype=np.int) for i in range(len(colors)-1): if m < 1: break result[i] = np.random.hypergeometric(colors[i], remaining[i+1], m) m -= result[i] result[-1] = m return result 

Например,

 >>> sample(10, [2, 4, 8, 16]) array([2, 3, 1, 4]) 

Следующее должно работать:

 def make_sampling_arr(n_k): out = [ x for s in [ [i] * n_k[i] for i in range(len(n_k)) ] for x in s ] return out np.random.choice(make_sampling_arr(n_k), m) 
  • Захват высокой многоколоничности в статистических моделях
  • Лучший способ масштабирования матричных переменных в схеме линейного программирования SCIPY
  • Как построить эмпирический cdf в matplotlib в Python?
  • Что это за массив Python? Он уже существует в Python?
  • py2exe и numpy не успевают
  • Лучший способ написать функцию Python, которая объединяет гауссово?
  • Python: 1d массивная круговая свертка
  • Поместите данные в список особого вида
  • Python - лучший язык программирования в мире.