假设我有N个对象,我想将它们划分为不同大小的M个桶。铲斗越大,它应该接收的物体就越多。
我目前已经解决了以下问题,但对我来说这看起来有些过分。我现在正在用python / numpy / scipy实现这个问题,这个代码将在我的计算密集型科学应用程序中经常执行。
首先,我生成一个离散的概率分布:
bucket_sizes = numpy.array([10., 7., 3., 20.])
bucket_ratios = bucket_sizes / bucket_sizes.sum()
dist = scipy.stats.rv_discrete(values=(range(bucket_sizes.size), bucket_ratios))
然后,我生成N个样本:
sample = dist.rcv(size=N)
最后,我计算样本
中每个桶id的出现次数bucket_id, counts = numpy.unique(sample, return_counts=True)
我现在要在counts
内的每个存储桶中放置元素的数量。
虽然这有效,但我觉得我应该能够更快地做到这一点,而不会生成ID列表然后计数(和排序)。
想法?
修改
作为参考,我找到了一个相应但更快的纯粹numpy解决方案。
_, counts = numpy.unique(numpy.random.choice(N, bucket_ratios), return_counts=True)
答案 0 :(得分:1)
从问题中不清楚是否需要随机分配,以及"桶大小"确定分配给桶的相对概率。这种随机分布称为multinomial distribution
。您可以使用numpy.random.multinomial
从多项分布中绘制样本。例如:
In [32]: bucket_sizes
Out[32]: array([10, 7, 3, 20])
In [33]: N
Out[33]: 100
In [34]: p = bucket_sizes / float(bucket_sizes.sum())
In [35]: p
Out[35]: array([ 0.25 , 0.175, 0.075, 0.5 ])
In [36]: np.random.multinomial(N, p)
Out[36]: array([25, 24, 4, 47])
In [37]: np.random.multinomial(N, p)
Out[37]: array([32, 15, 8, 45])