como calcular a mediana em execução com eficiência
Peguei emprestado algum código tentando implementar uma função para calcular a mediana em execução para uma tonelada de dados. O atual é muito lento para mim (A parte complicada é que eu preciso excluir todos os zeros da caixa de execução) Abaixo está o 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 bem, a única desvantagem é que é muito lento. Alguém poderia me ajudar a melhorar o código para ser mais eficiente? Obrigado.
Depois de explorar todas as possibilidades, o seguinte código simples pode ser calculado de forma comparável e 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
Obrigado @Divakar.