Cómo calcular la mediana de carrera eficientemente
Tomé prestado algún código tratando de implementar una función para calcular la mediana en ejecución de una tonelada de datos. El actual es demasiado lento para mí (La parte difícil es que necesito excluir todos los ceros del cuadro de ejecución) Debajo está el código:
from itertools import islice
from collections import deque
from bisect import bisect_left,insort
def median(s):
sp = [nz for nz in s if nz!=0]
print sp
Mnow = len(sp)
if Mnow == 0:
return 0
else:
return np.median(sp)
def RunningMedian(seq, M):
seq = iter(seq)
s = []
# Set up list s (to be sorted) and load deque with first window of seq
s = [item for item in islice(seq,M)]
d = deque(s)
# Sort it in increasing order and extract the median ("center" of the sorted window)
s.sort()
medians = [median(s)]
for item in seq:
old = d.popleft() # pop oldest from left
d.append(item) # push newest in from right
del s[bisect_left(s, old)] # locate insertion point and then remove old
insort(s, item) # insert newest such that new sort is not required
medians.append(median(s))
return medians
Funciona bien, el único inconveniente es que es demasiado lento. ¿Alguien podría ayudarme a mejorar el código para ser más eficiente? Gracias.
Después de explorar todas las posibilidades, el siguiente código simple puede calcular de manera comparable de manera eficiente:
def RunningMedian(x,N):
idx = np.arange(N) + np.arange(len(x)-N+1)[:,None]
b = [row[row>0] for row in x[idx]]
return np.array(map(np.median,b))
#return np.array([np.median(c) for c in b]) # This also works
Gracias @Divakar.