首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >低空取样

低空取样
EN

Stack Overflow用户
提问于 2014-05-05 19:11:36
回答 3查看 2K关注 0票数 3

我有一个表示分类数据的一维数组A(其中每个条目都是某个类别的元素数):

代码语言:javascript
复制
A = array([ 1, 8, 2, 5, 10, 32, 0, 0, 1, 0])

我正在尝试编写一个函数样例(A,N),以生成一个数组B,其中包含从A中随机绘制元素所生成的N个元素(保留类别):

代码语言:javascript
复制
>>> sample(A, 20)
array([ 1, 3, 0, 1, 4, 11, 0, 0, 0, 0])

我写了这个:

代码语言:javascript
复制
def sample(A, N):
    AA = A.astype(float).copy()
    Z = zeros(A.shape)
    for _ in xrange(N):
        drawn = random.multinomial(1, AA/AA.sum())
        Z = Z + drawn
        AA = AA - drawn
    return Z.astype(int)

也许这是很天真的,有没有更好/更快的方法去做呢?或者用一些快速的矮胖函数?编辑:这是不清楚的:它必须没有替代!

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2014-05-05 20:57:21

据我所知,比其他人更快。但可能需要更多的记忆。

代码语言:javascript
复制
import random 
from collections import Counter

def sample2(A,N):
    distribution = [i for i, j in enumerate(A) for _ in xrange(j)]
    sample = Counter(random.sample(distribution, N))
    return [sample[i] for i in xrange(len(A))]


In [52]: A = np.random.randint(0, 100, 500)

In [53]: %timeit sample(A, 100) #Original
100 loops, best of 3: 2.71 ms per loop

In [54]: %timeit sample2(A, 100) #my function
1000 loops, best of 3: 914 µs per loop

In [55]: %timeit sample3(A, 100) #sftd function
100 loops, best of 3: 8.33 ms per loop
票数 2
EN

Stack Overflow用户

发布于 2014-05-05 20:50:27

这可能不是最优雅的解决方案,但它大约是3倍的速度。它使用numpy.random.choice,它有一个布尔替换选项(在本例中设置为False -即不替换)。其余的代码是:

  • 设置选项数组,其中包含索引nn计数,例如对于A=[2,0,3,1],您将得到choices=[0,0,2,2,2,3]。请注意,它们中的每一个都具有相同的概率,因此不需要创建概率数组。
  • 将numpy函数调用选择的值转换为所需的输出数组。vals数组的每个元素都将是从choices数组中选择的索引,因此您需要为所选的每个索引在适当的B元素中添加1。

我希望这是有意义的!以下是代码:

代码语言:javascript
复制
def sample_2(A, N):
    # Create array of choices (indicies)
    choices = []
    for n in xrange(len(A)):
        for _ in xrange(A[n]):
            choices.append(n)
    # Randomly choose from these indicies
    vals = numpy.random.choice(choices, N, False)
    # Count up the chosen indicies
    B = numpy.zeros(len(A), dtype=int)
    for index in xrange(N):
        B[vals[index]] += 1
    return B

每个函数的10000次调用的速度测试结果:

代码语言:javascript
复制
Original: 3.0517 s
Method_2: 0.9968 s
票数 2
EN

Stack Overflow用户

发布于 2014-05-05 20:30:35

我会这样做:

代码语言:javascript
复制
def sample(A, N):
        population = np.zeros(sum(A))
        counter = 0
        for i, x in enumerate(A):
                for j in range(x):
                        population[counter] = i
                        counter += 1

        sampling = population[np.random.randint(0, len(population), N)]
        return np.histogram(sampling, bins = np.arange(len(A)+1))[0]

我们要做的是建立一个由直方图A定义的种群,然后从它随机抽样。如果现实世界的情况有N大和和(A)小,和(或)你需要为一个固定的A多次样本A,这应该是更好的。您要做的是在函数调用之外构建与A对应的总体,并将sample(population, N)定义为上面的最后两行。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/23479970

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档