In un programma pylab (che potrebbe probabilmente essere un programma MATLAB pure) Ho una matrice NumPy di numeri che rappresentano distanze: d[t]
rappresenta l'distanza al momento t
(e il periodo di tempo dei miei dati è len(d)
unità di tempo).lunghezza scoperta di sequenze di valori identici in una matrice NumPy (run-length encoding)
Gli eventi a cui sono interessato sono quando la distanza è inferiore a una determinata soglia e voglio calcolare la durata di questi eventi. È facile ottenere una serie di booleani con b = d<threshold
e il problema si riduce al calcolo della sequenza delle lunghezze delle parole True-only in b
. Ma non so come farlo in modo efficiente (cioè usando le primitive numpy), e ho fatto ricorso a walk the array e per fare il rilevamento del cambio manuale (cioè inizializzare contatore quando il valore passa da False a True, aumentare il contatore fintanto che il valore è True e invia il contatore alla sequenza quando il valore torna a False). Ma questo è tremendamente lento.
Come rilevare in modo efficiente quel tipo di sequenze in array numpy?
Di seguito è riportato un codice python che illustra il mio problema: il quarto punto prende un tempo molto lungo per apparire (se non, aumentare la dimensione della matrice)
from pylab import *
threshold = 7
print '.'
d = 10*rand(10000000)
print '.'
b = d<threshold
print '.'
durations=[]
for i in xrange(len(b)):
if b[i] and (i==0 or not b[i-1]):
counter=1
if i>0 and b[i-1] and b[i]:
counter+=1
if (b[i-1] and not b[i]) or i==len(b)-1:
durations.append(counter)
print '.'
Hmmmmm ... l'ultimo sembra familiare. ;) – gnovice
Grazie mille! La diff/where solution è esattamente ciò che avevo in mente (per non parlare del fatto che è circa 10 volte più veloce rispetto alle altre soluzioni). Chiama "non troppo intelligente" se vuoi, ma vorrei essere abbastanza intelligente da inventarlo :-) – Gyom
@gnovice, non lo faccio matlab (abbastanza divertente mia figlia, ora un dottorando in avanzato radio engineering, fa ;-), ma ora guardando la tua risposta, vedo le analogie - ottieni la fine dei run meno le start-of-run, prendi quelle individuando lo spot <0 and > 0 nelle differenze e bit con zero per assicurarsi che tutte le esecuzioni finiscano. Indovina che non ci sono molti modi per risolvere questo problema di "lunghezze"! -) –