将M个桶中的N个元素除以与桶大小成比例的不同大小

时间:2016-03-14 23:41:28

标签: python numpy scipy

假设我有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)

1 个答案:

答案 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])