2017-11-26 16 views
0

관측 시간 배열이 ts이고, 각 관측 값이 vs에있는 것으로 가정합니다. 관측 시간은 경과 시간 수 (0부터 시작)로 취해지며 중복을 포함 할 수 있습니다. 나는 유일한 관측 시간 당 최대 관측 값에 해당하는 지표를 찾고 싶다. 나는 몇 달 전에 물었던 unlike a similar question 값과는 대조적으로 색인을 요구하고 있습니다. 이렇게하면 다양한 배열에 동일한 인덱스를 적용 할 수 있습니다. 다음은 훨씬 더 큰 데이터 세트의 코드를 적용하기 위해 사용하고자하는 샘플 데이터 세트입니다.배열 B의 고유 값에 해당하는 배열 A의 모든 최대 값의 인덱스를 구하는 방법은 무엇입니까?

import numpy as np 
ts = np.array([0, 0, 1, 2, 3, 3, 3, 4, 4, 5, 6, 7, 8, 8, 9, 10]) 
vs = np.array([500, 600, 550, 700, 500, 500, 450, 800, 900, 700, 600, 850, 850, 900, 900, 900]) 

현재 나의 접근 방식은 중복 시간이없는 지점에서 값 배열을 분할하는 것입니다.

condition = np.where(np.diff(ts) != 0)[0]+1 
ts_spl = np.split(ts, condition) 
vs_spl = np.split(vs, condition) 

print(ts_spl) 
>> [array([0, 0]), array([1]), array([2]), array([3, 3, 3]), array([4, 4]), array([5]), array([6]), array([7]), array([8, 8]), array([9]), array([10])] 

print(vs_spl) 
>> [array([500, 600]), array([550]), array([700]), array([500, 500, 450]), array([800, 900]), array([700]), array([600]), array([850]), array([850, 900]), array([900]), array([900])] 

이 경우 중복되는 최대 값은 중복되어야합니다. 이 예를 감안할 때, 반환 된 인덱스는 다음과 같습니다

나는 아직 내 목적을 위해이 알고리즘을 적용하지 못하고 있지만
[1, 2, 3, 4, 5, 8, 9, 10, 11, 13, 14, 15] 
# indices = 4,5,6 correspond to values = 500, 500, 450 ==> count indices 4,5 
# I might modify this part of the algorithm to return either 4 or 5 instead of 4,5 at some future time 

, 나는 vs_spl의 각 이전에 분할 배열의 크기를 악용 할 수 있어야한다 생각 색인 카운터를 유지합니다. 큰 데이터 세트 (패딩 전에 배열 당 10,000 개의 요소, 패딩 이후에 배열 당 70,000 개의 요소)에 대해이 접근법을 사용할 수 있습니까? 그렇다면 어떻게 적응시킬 수 있습니까? 그렇지 않다면 여기서 유용한 다른 접근법은 무엇입니까?

답변

1

70,000은 대단히 크지 않으므로 가능해야합니다. 그러나 분할을 피하고 관련 ufuncs 메서드를 .reduceat 사용하는 것이 더 빠릅니다. reduceat은 청크에 적용되는 축소와 비슷하지만 청크를 제공 할 필요가 없으므로 reduceat에게 알려야합니다. 예 : like so

import numpy as np 


N = 10**6 
ts = np.cumsum(np.random.rand(N) < 0.1) 
vs = 50*np.random.randint(10, 20, (N,)) 

#ts = np.array([0, 0, 1, 2, 3, 3, 3, 4, 4, 5, 6, 7, 8, 8, 9, 10]) 
#vs = np.array([500, 600, 550, 700, 500, 500, 450, 800, 900, 700, 600, 850, 850, 900, 900, 900]) 


# flatnonzero is a bit faster than where 
condition = np.r_[0, np.flatnonzero(np.diff(ts)) + 1, len(ts)] 
sizes = np.diff(condition) 
maxima = np.repeat(np.maximum.reduceat(vs, condition[:-1]), sizes) 
maxat = maxima == vs 
indices = np.flatnonzero(maxat) 
# if you want to know how many maxima at each hour 
nmax = np.add.reduceat(maxat, condition[:-1]) 
+0

현재 모바일. 나는 이것을 약 1 시간 만에 시험하고 놀 수있다. 감사! – mikey

+0

나는'condition = np.r_ [0, np.flatnonzero (np.diff (ts)) + 1, len (ts)]'줄을 제외한 모든 것을 따라갈 것이라고 생각한다. 내 이해를 위해,'np.flatnonzero'는 0이 아닌 값에 대한 연대순으로 인덱스를 반환하며, 이는 연속적인 관찰 시간에 대해 점검합니다. '.reduceat'에 대한 팁이 도움이되었습니다. 문서에서'np.r_'이 배열을 만들 수 있지만이 줄에서 그 사용법을 설명 할 수 있습니까? – mikey

+1

'flatnonzero'는 코드에서'where'와 똑같습니다. 벡터와 스칼라에 적용된'r_'은 바로 그것들을 연결합니다, 그래서이 경우에 우리는 왼쪽에 0을 추가하고 오른쪽에 길이를 더합니다. 그런 식으로 우리는 내부 경계뿐만 아니라 외부 경계도 갖게됩니다. 예를 들어 다음 줄 에서처럼 청크의 크기를 계산할 때 유용합니다. –