2017-12-08 17 views
1

Numpy는 범주 형 분포에서 샘플링 할 수있는 random.choice 함수를 가지고 있습니다. 이것을 축에 대해 어떻게 반복 할 것입니까? 무슨 뜻인지 설명하기 위해 여기에 현재 코드가 있습니다 :주어진 축을 따라 주어진 2D 배열에 대해`numpy.random.choice`를 벡터화합니다

categorical_distributions = np.array([ 
    [.1, .3, .6], 
    [.2, .4, .4], 
]) 
_, n = categorical_distributions.shape 
np.array([np.random.choice(n, p=row) 
      for row in categorical_distributions]) 

이상적으로 for 루프를 제거하고 싶습니다.

+0

을위한 작업 ['지도'] (HTTPS처럼 보인다. python.org/3/library/functions.html#map). – Galen

+0

@ Galen 성능 수치는 게시 된 루피 솔루션과 비슷할 것입니다. – Divakar

+0

@Divakar Agreed. – Galen

답변

1

여기 확률의 2D 배열로 a과, 행마다 임의의 인덱스를 얻기 위해 하나 벡터화 방법 -

(a.cumsum(1) > np.random.rand(a.shape[0])[:,None]).argmax(1) 

일반화 덮는 두 2D 어레이의 행 및 열을 따라 -

def random_choice_prob_index(a, axis=1): 
    r = np.expand_dims(np.random.rand(a.shape[1-axis]), axis=axis) 
    return (a.cumsum(axis=axis) > r).argmax(axis=axis) 

백만 번 넘게 실행하여 주어진 샘플을 확인해 봅시다. -

In [589]: a = np.array([ 
    ...:  [.1, .3, .6], 
    ...:  [.2, .4, .4], 
    ...: ]) 

In [590]: choices = [random_choice_prob_index(a)[0] for i in range(1000000)] 

# This should be close to first row of given sample 
In [591]: np.bincount(choices)/float(len(choices)) 
Out[591]: array([ 0.099781, 0.299436, 0.600783]) 
// 문서 : 16,

런타임 테스트

원래 깨어나 길 - - 더 큰 배열에

def loopy_app(categorical_distributions): 
    m, n = categorical_distributions.shape 
    out = np.empty(m, dtype=int) 
    for i,row in enumerate(categorical_distributions): 
     out[i] = np.random.choice(n, p=row) 
    return out 

타이밍

In [593]: a = np.array([ 
    ...:  [.1, .3, .6], 
    ...:  [.2, .4, .4], 
    ...: ]) 

In [594]: a_big = np.repeat(a,100000,axis=0) 

In [595]: %timeit loopy_app(a_big) 
1 loop, best of 3: 2.54 s per loop 

In [596]: %timeit random_choice_prob_index(a_big) 
100 loops, best of 3: 6.44 ms per loop