2017-05-24 6 views
2

두 개의 동일한 길이의 배열이 있습니다. 첫 번째 배열은 부울 배열이고 두 번째 배열은 해당 값을 포함합니다.bool python에 따라 배열 부분의 중앙값을 구하십시오.

flag = [0,0,0,1,1,0,0,0,1,1,1,1,0,1,1] 
values = [1,5,6,8,5,6,2,0,1,9,3,8,3,6,2] 

부울 행렬의 각 부분 1에 해당하는 중앙값을 포함하는 중간 값의 배열을 반환하고자합니다.

flag = [0,0,0,1, 1, 0,0,0, 1, 1, 1, 1, 0,1,1] 
result = [0,0,0,6.5,6.5,0,0,0,5.5,5.5,5.5,5.5,0,4,4] 

내 unesthetic 접근하는 것입니다 :

result = np.zeros(values.shape[0]) 
vect = [] 
idx = [] 
for n in np.arange(result.size): 
    if flag[n] > 0: 
     vect.append(values[n]) 
     idx.append(n) 
    elif flag[n] == 0: 
     result[idx] = np.median(vect) 
     vect = [] 
     idx = [] 
    result[idx] = np.median(vect) 

그것은 잘 작동하지만 그것은 매우 파이썬 내가 매우 큰 배열 작업을하기 때문에 매우 느린 아니다.

답변

2

np.diff을 사용하여 0과 1 사이의 전환을 찾을 수 있습니다. 그런 다음 0/1과 1/0 전환의 쌍을 반복하고 중간 값을 모두 가져옵니다.

결과 루프는 1의 각 그룹을 반복합니다.

flag = [0,0,0,1,1,0,0,0,1,1,1,1,0,1,1] 
values = [1,5,6,8,5,6,2,0,1,9,3,8,3,6,2] 

d = np.diff(np.concatenate([[0], flag, [0]])) # Add and append a 0 so the procedure also works if flags start or end with 1. 

begin = np.flatnonzero(d==1) 
end = np.flatnonzero(d==-1) 

result = np.zeros_like(values, dtype=float) 

for a, b in zip(begin, end): 
    result[a:b] = np.median(values[a:b]) 

print(result) 
# [ 0. 0. 0. 6.5 6.5 0. 0. 0. 5.5 5.5 5.5 5.5 0. 4. 4. ] 
+0

이 문제는 분명합니다. – Divakar

+0

감사! 10,000 요소 배열의 경우 약 100 배 빠릅니다. –