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.

Respuestas a la pregunta(2)

Su respuesta a la pregunta