2017-11-28 2 views
1

ich ein numpy Array so haben:NumPy wo als Bereich Indizes

a = numpy.array([1, 1, 1, 0, 0, 0, 1, 1, 1, 0, 0, 0]) 

Das Ziel ist es, die Bereiche von Nullen und Einsen zu finden, die Start- und End-Indizes. Ich möchte diese Bereiche in einem anderen numpy Array verwenden, das Zeitstempel enthält, um herauszufinden, wie viel Zeit jede Nullphase benötigt. So etwas Ähnliches:

dur = numpy.diff(time[start idx, end idx]) 

jedoch numpy wo gibt mir alle Indizes:

numpy.where(a==0) 
(array([ 3, 4, 5, 9, 10, 11], dtype=int64),) 

Ich würde nur idx jeder Phase Null beginnen und enden müssen, wie [[3,5], [9 , 11]]. Wie kann ich das erreichen?

Antwort

1

Hier ist ein Ansatz -

def start_stop(a, val=0): 
    n = np.concatenate(([False], a==val,[False])) 
    idx = np.flatnonzero(np.diff(n)) 
    # or idx = np.flatnonzero(n[1:] != n[:-1]) 
    return idx[::2], idx[1::2]-1 

Kürzere Wege -

def start_stop_v2(a, val=0): 
    idx = np.flatnonzero(np.diff(np.r_[0,a==val,0])) 
    return idx[::2], idx[1::2]-1 

One-Liner -

np.flatnonzero(np.diff(np.r_[0,a==0,0])).reshape(-1,2) - [0,1] 

Probelauf -

In [324]: a 
Out[324]: array([1, 1, 1, 0, 0, 0, 1, 1, 1, 0, 0, 0]) 

In [325]: start_stop(a, val=0) 
Out[325]: (array([3, 9]), array([ 5, 11])) 

In [326]: start_stop_v2(a, val=0) 
Out[326]: (array([3, 9]), array([ 5, 11])) 

In [327]: np.flatnonzero(np.diff(np.r_[0,a==0,0])).reshape(-1,2) - [0,1] 
Out[327]: 
array([[ 3, 5], 
     [ 9, 11]]) 

Re-Verwendung von np.where(a==val)

es zu lösen erneut mit Ergebnis np.where(a==val) -

In [388]: idx = numpy.where(a==0)[0] 

In [389]: mask = np.r_[True,np.diff(idx)!=1,True] 

In [390]: idx[mask[:-1]] # starts 
Out[390]: array([3, 9]) 

In [391]: idx[mask[1:]] # stops 
Out[391]: array([ 5, 11]) 
+0

Gibt es eine Möglichkeit auf dem Ergebnis von wo (Array arbeiten ([3, 4 , 5, 9, 10, 11], dtype = int64)), um die fortlaufenden Zahlen zu gruppieren? Dann könnte ich an kleineren numply Arrays arbeiten und etwas Zeit im Vergleich zu den ursprünglichen Daten sparen. – dito

+0

@MichaelHaus Besuche die Änderungen am Ende. – Divakar

+0

Ich hätte schwören können, ich habe gesehen, dass du diese Frage bereits ein Dutzend Mal beantwortet hast, @Divakar. Zu dem Punkt, auf dem ich Ihre Userpage trollte, um zu versuchen, den Dupe Link zu finden, aber ohne Erfolg. –