随机均匀分配采样的多项式值

时间:2014-04-21 22:44:03

标签: python numpy random statistics random-sample

我正在使用np.random.multinomial对多项分布进行抽样M次(给定概率[X_0 X_1 .. X_n]它返回从指定多项式中抽样的[C_0 C_1 ... C_n],其中\sum_i C_i = M )。给定这些采样值(C_i),我想将它们随机均匀地分配给我拥有的一些对象。

目前我正在做的是:

draws = np.random.multinomial(M, probs, size=1)
draws = draws[0]
draws_list = []
for idx,num in enumerate(draws):
    draws_list += [idx]*num
random.shuffle(draws_list)

然后draws_list是一个随机抽样的采样值列表。

问题是填充draws_list(for循环)非常慢。有更好/更快的方法吗?

1 个答案:

答案 0 :(得分:1)

试试这段代码。这个策略是先分配内存,然后再填充数据。

draws_list1 = np.empty(M, dtype=np.int)
acc = 0
for idx, num in enumerate(draws):
    draws_list1[acc:acc+num].fill(idx)
    acc += num

这是分析的完整代码。

import numpy as np
import cProfile

M=10000000

draws = np.random.multinomial(M, [1/6.]*6, size=1)
draws = draws[0]

draws_list1 = np.empty(M, dtype=np.int)

def impl0():
    draws_list0 = []
    for idx, num in enumerate(draws):
        draws_list0 += [idx]*num
    return draws_list0

def impl1():
    acc = 0
    for idx, num in enumerate(draws):
        draws_list1[acc:acc+num].fill(idx)
        acc += num
    return draws_list1

cProfile.run("impl0()")
cProfile.run("impl1()")

以下是cProfile的结果。如果语句np.empty位于函数impl1中,则0.020 seconds已过了。

     3 function calls in 0.095 seconds

 Ordered by: standard name

 ncalls  tottime  percall  cumtime  percall filename:lineno(function)
      1    0.020    0.020    0.095    0.095 <string>:1(<module>)
      1    0.076    0.076    0.076    0.076 prof.py:11(impl0)
      1    0.000    0.000    0.000    0.000 {method 'disable' of '_lsprof.Profiler' objects}


       9 function calls in 0.017 seconds

 Ordered by: standard name

 ncalls  tottime  percall  cumtime  percall filename:lineno(function)
      1    0.000    0.000    0.017    0.017 <string>:1(<module>)
      1    0.000    0.000    0.017    0.017 prof.py:17(impl1)
      1    0.000    0.000    0.000    0.000 {method 'disable' of '_lsprof.Profiler' objects}
      6    0.017    0.003    0.017    0.003 {method 'fill' of 'numpy.ndarray' objects}