2013-10-13 2 views
0

아래 함수에서 "sortedlist"라고하는 41000x3 numpy 배열이 있습니다. 세 번째 열은 값의 묶음을 가지며 그 중 일부는 중복되고 다른 것은 값이 아닌 값입니다. sortedlist [:, 2] 인 세 번째 열에서 고유 값 (중복 없음)의 샘플을 가져오고 싶습니다. numpy.random.sample (sortedlist [:, 2], sample_size)을 사용하면이 작업을 쉽게 수행 할 수 있다고 생각합니다. 문제는 그 값뿐만 아니라 마지막 열에 numpy.random.sample에서 얻은 무작위로 선택된 값이있는 세 개의 열 모두를 반환하고 싶습니다.파이썬 배열의 세 번째 열에서 고유 한 난수 값 선택

편집 : 고유 한 값으로 한 번만 나타나는 임의의 값을 선택하고 싶습니다. 내가 배열했다 그래서 경우

new_array_1 = [[5, 3, 9] 
       [3, 7, 1] 
       [5, 3, 2] 
       [5, 2, 8]] 

하지만 내가 좋아하는 뭔가를하지 않으 :

array = [[0, 6, 2] 
     [5, 3, 9] 
     [3, 7, 1] 
     [5, 3, 2] 
     [3, 1, 1] 
     [5, 2, 8]] 

을 내가 세 번째 열에 4 개 값을 선택하고 싶었, 나는 new_array_1 같은 뭔가를 얻으려면 3 열에서 두 값이 동일 new_array_2 :

new_array_2 = [[5, 3, 9] 
       [3, 7, 1] 
       [5, 3, 2] 
       [3, 1, 1]] 

나는 임의의 값을 선택하는 코드를 가지고 있지만 기준없이 그들은 세 번째 열에서 중복되지 않아야 함.

samplesize = 100 

rand_sortedlist = sortedlist[np.random.randint(len(sortedlist), size = sample_size),:]] 

나는이

array_index = where(array[:,2] == sample(SelectionWeight, sample_size)) 

같은 것을 수행하여이 기준을 적용하기 위해 노력하고있어하지만 내가 곧 정상 궤도에있어 잘 모르겠어요. 어떤 도움이라도 대단히 감사하겠습니다!

+1

"고유 값 ** (중복 없음) ** 샘플을 가져오고 싶습니다. 두 번 이상 나타나는 경우 샘플링에서 값을 제외 시키겠다는 의미입니까? 또는 모든 요소가 고유 한 목록에서 샘플링하고 싶습니까? 또는 대체하지 않고 샘플링하기를 원하므로 무작위로 샘플링 된 값이 절대로 중복되지 않습니까? 아니면 어떤 조합? 일부 샘플 데이터가 도움이됩니다. – Brionius

+0

세 번째 열에 0 또는 1부터 최대 값까지의 모든 숫자가 포함되어 있습니까? 아니면 일부 중복되거나 시퀀스에 간격이 있습니까? –

답변

0

데이터를 여러 번 통과시키지 않는 영리한 방법을 생각하면 안됩니다. (때로는 NumPy와 아직 갈 수있는 가장 빠른 방법입니다 순수 파이썬보다 훨씬 빠르지 만 그것은 결코 바로 느낌이 없습니다.) 순수 파이썬에서

, 나는

을하는 줄 것이라고

def draw_unique(vec, n): 
    # group indices by value 
    d = {} 
    for i, x in enumerate(vec): 
     d.setdefault(x, []).append(i) 

    drawn = [random.choice(d[k]) for k in random.sample(d, n)]   
    return drawn 

처럼 뭔가를 할 것

>>> a = np.random.randint(0, 10, (41000, 3)) 
>>> drawn = draw_unique(a[:,2], 3) 
>>> drawn 
[4219, 6745, 25670] 
>>> a[drawn] 
array([[5, 6, 0], 
     [8, 8, 1], 
     [5, 8, 3]]) 
내가 np.bincountscipy.stats.rankdata 몇 가지 트릭을 생각할 수

하지만 그들은 내 머리를 다치게, 항상 .. 내가 벡터화하는 방법을 볼 수 없습니다 말에 한 단계 인이 바람이 난 벡터화 아니에요 경우 위의 모든 것을 사용할 수도 있습니다. 최소한 간단합니다.

0

나는 이것이 당신이 원하는 것을 할 것이라고 믿습니다. 실행 시간은 난수를 생성하는 데 사용하는 방법에 의해 거의 확실하게 좌우됩니다. (예외적으로 데이터 집합이 거대하지만 적은 수의 행만 필요로하는 경우 매우 적은 수의 난수를 그릴 필요가 있습니다.) 따라서 순수 파이썬 메서드보다 훨씬 빠르게 실행될지 확신하지 못합니다.

# arrayify your list of lists 
# please don't use `array` as a variable name! 
a = np.asarray(arry) 

# sort the list ... always the first step for efficiency 
a2 = a[np.argsort(a[:, 2])] 

# identify rows that are duplicates (3rd column is non-increasing) 
# Note this has length one less than a2 
duplicate_rows = np.diff(a2[:, 2]) == 0) 

# if duplicate_rows[N], then we want to remove row N and N+1 
keep_mask = np.ones(length(a2), dtype=np.bool) # all True 
keep_mask[duplicate_rows] = 0 # remove row N 
keep_mask[1:][duplicate_rows] = 0 # remove row N + 1 

# now actually slice the array 
a3 = a2[keep_mask] 

# select rows from a3 using your preferred random number generator 
# I actually prefer `random` over numpy.random for sampling w/o replacement 
import random 
result = a3[random.sample(xrange(len(a3)), DESIRED_NUMBER_OF_ROWS)]