2017-11-10 5 views
2

천개의 별개의 "클러스터"가있는 형태 (50, 10000, 10000)의 NumPy 배열이 있다고 가정합니다. 예를 들어, 내가 지금 같은 마스크 만들기 위해 각각의 클러스터를 반복하고 싶은 곳 등 단지 1 초, 2 초와 다른 작은 볼륨, 작은 볼륨이있을 것입니다 :효율적인 마스크 생성 - Numpy/Python

for i in np.unique(arr)[1:]: 
    mask = arr == i 
    #do other stuff with mask 

각 마스크 만들기는 약 15 초 소요 , 1000 클러스터를 반복하는 데는 4 시간 이상 걸립니다. 코드의 속도를 높일 수있는 방법이 있을까요? 아니면 배열의 각 요소를 반복적으로 반복하는 것을 피할 수 없기 때문에 최선입니까?

편집 : 배열의 DTYPE은 스파 스 내가 arr 있으리라 믿고있어 UINT16

+0

당신은 5GB 용량 NumPy와 배열을? –

+0

어떻게 그 마스크를 사용할 계획입니까? 모든 마스크를 사전 계산하면 거대한 마스크 배열이 생기기 때문에 좋은 생각이라고 생각하지 마십시오. – Divakar

+0

@ cᴏʟᴅsᴘᴇᴇᴅ 죄송합니다. dtype은 uint16이므로 5GB가 아닙니다. – onepint16oz

답변

1

입니다 :

  • 당신이 클러스터가 작은 말, 1000 개 클러스터는 타일 배열을하지 않을된다 큰
  • 당신이 np.unique(arr)[1:] 반복, 그래서 내가 처음 고유 한 값이 나는 것이 경우 0

가정 활용 좋습니다 scipy.sparse.csr_matrix

from scipy.sparse import csr_matrix 
sp_arr = csr_matrix(arr.reshape(1,-1)) 

이 한 행 압축 스파 스 열 배열에 당신의 큰 조밀 한 배열을집니다. 희소 배열은 2 차원 이상을 좋아하지 않으므로,이 값은 엄청난 색인을 사용하여 속입니다. 이제 sp_arrdata (클러스터 레이블), indices (ravelled 인덱스) 및 indptr (여기에는 하나의 행만 있기 때문에 간단합니다)이 있습니다. 그래서

for i in np.unique(sp_arr.data): # as a bonus this `unique` call should be faster too 
    x, y, z = np.unravel_index(sp_arr.indices[sp_arr.data == i], arr.shape) 

훨씬 더 효율적이 x, y, z mask에서 True 값의 인덱스이다

for i in np.unique(arr)[:1]: 
    x, y, z = np.nonzero(arr == i) 

동등한 좌표를 주어야한다. 거기에서 mask을 재구성하거나 색인을 처리 할 수 ​​있습니다 (권장).

는 또한 numpy으로 순수하게이 작업을 수행하고, 여전히 끝에 부울 마스크를 가지고 있지만, 조금 더 적은 메모리 효율성 수 :

all_mask = arr != 0 # points assigned to any cluster 
data = arr[all_mask] # all cluster labels 
for i in np.unique(data): 
    mask = all_mask.copy() 
    mask[mask] = data == i # now mask is same as before 
+0

와우. 답변 감사합니다. 인덱스로 작업하는 것은 마스크를 다시 만드는 것보다 훨씬 빠릅니다. numpy/scipy를 활용하는 방법에 대해 더 자세히 알 수있는 리소스가 있습니까? – onepint16oz

+1

그 리소스는 거의 온라인 문서이며 StackOverflow입니다. 질문을 검색하거나 Divakar, MSiefert, COLDSPEED 등의 게시물 기록을 탐색 해보십시오. –

관련 문제