2016-07-21 3 views
1

사전을 사용하여 배열 목록의 값을 바꾸는 데 성능 문제가 있습니다.큰 배열 목록의 값 바꾸기 (성능)

의이 내 사전입니다 가정 해 봅시다 :

# Create a sample dictionary 

keys = [1, 2, 3, 4] 
values = [5, 6, 7, 8] 
dictionary = dict(zip(keys, values)) 

그리고이 배열의 내 목록입니다

# import numpy as np 

# List of arrays 
listvalues = [] 

arr1 = np.array([1, 3, 2]) 
arr2 = np.array([1, 1, 2, 4]) 
arr3 = np.array([4, 3, 2]) 

listvalues.append(arr1) 
listvalues.append(arr2) 
listvalues.append(arr3) 

listvalues 
>[array([1, 3, 2]), array([1, 1, 2, 4]), array([4, 3, 2])] 

나는 다음을 사용하여 습니 nummpy 배열의 모든 값을 대체하기 위해 다음과 같은 기능을 사용하여 사전 :

# Replace function 

def replace(arr, rep_dict): 

    rep_keys, rep_vals = np.array(list(zip(*sorted(rep_dict.items())))) 
    idces = np.digitize(arr, rep_keys, right=True) 

    return rep_vals[idces] 

이 기능은 정말 빠릅니다. 그러나 ar의 목록을 반복해야합니다. 각 배열에이 함수를 적용하려면 다음과 같이하십시오.

replaced = [] 
for i in xrange(len(listvalues)): 
    replaced.append(replace(listvalues[i], dictionary)) 

수천 개의 배열을 반복해야하므로 병목 현상이 발생합니다. for-loop를 사용하지 않고 어떻게 동일한 결과를 얻을 수 있습니까? 결과가 입력과 동일한 형식 (값이 대체 된 배열 목록)이 중요합니다.

많은 감사합니다 !!

+0

; listvalues는 길이가 매우 짧은 여러 개의 매우 짧은 배열의 매우 긴 시퀀스입니까? 이 짧은 배열의 길이에 자연적인 상한선이 있습니까? –

+0

기본적으로 배열은 매우 짧지 만 배열이나 목록의 길이에 자연적인 상한선은 없습니다. 대부분의 배열은 len 20보다 길지 않습니다. 희망이 도움이됩니다! – cf2

+0

병목 현상은 루프가 아니라 '대체'기능입니다. 루프에서 중요한 일이 일어나지 않으므로 루프를 대체하거나 병렬 처리하는 성능을 향상시켜야합니다. – sirfz

답변

2

이렇게하면 numpy_indexed 패키지를 사용하여 효율적으로 트릭을 수행 할 수 있습니다. 'listvalues'의 모든 값이 'keys'에 있음이 보장되면 더욱 간단해질 수 있습니다. 그러나 아픈 것은 독자에게 운동으로 남겨 둡니다.

import numpy_indexed as npi 
arr = np.concatenate(listvalues) 
idx = npi.indices(keys, arr, missing='mask') 
remap = np.logical_not(idx.mask) 
arr[remap] = np.array(values)[idx[remap]] 
replaced = np.array_split(arr, np.cumsum([len(a) for a in listvalues][:-1])) 
+0

감사합니다. 이렇게하면 몇 초 안에 모든 값이 바뀝니다. :). 그러나 내 전체 데이터 집합에서'arr [remap] = ... '을 할 때 경고 메시지가 나타납니다. _DeprecationWarning : 할당 결과에 오류가 발생합니다. 인덱스 결과 모양이 값 배열 shape_과 일치하지 않기 때문일 수 있습니다. 다시 한번 감사드립니다. ! – cf2

+0

죄송합니다. 그 오류를 얻지도 않았고 그것에 익숙하지도 않았습니다. 그리고 나는 그것을 일으키는 원인이되는 단서를 당장 가지고 있지 않습니다. 어떤 버전을 사용하고 있습니까? –

+0

Python 2.7x. 알려 줘서 고마워. 나는 내일 더 많은 시험을 할 것이다 – cf2