Necesito filtrar una matriz para eliminar los elementos que están por debajo de un cierto umbral. Mi código actual es así:
threshold = 5
a = numpy.array(range(10)) # testing data
b = numpy.array(filter(lambda x: x >= threshold, a))
El problema es que esto crea una lista temporal, usando un filtro con función lambda (lento).
Como esta es una operación bastante simple, tal vez haya una función numerosa que lo haga de manera eficiente, pero no he podido encontrarla.
Pensé que otra forma de lograr esto podría ser ordenar la matriz, encontrar el índice del umbral y devolver una porción de ese índice en adelante, pero incluso si esto sería más rápido para entradas pequeñas (y no se notará de todos modos ), definitivamente es asintóticamente menos eficiente a medida que aumenta el tamaño de entrada.
¿Algunas ideas? ¡Gracias!
Actualización : también tomé algunas medidas, y la clasificación y el corte seguían siendo dos veces más rápido que el filtro de Python puro cuando la entrada era 100.000.000 de entradas.
In [321]: r = numpy.random.uniform(0, 1, 100000000)
In [322]: %timeit test1(r) # filter
1 loops, best of 3: 21.3 s per loop
In [323]: %timeit test2(r) # sort and slice
1 loops, best of 3: 11.1 s per loop
In [324]: %timeit test3(r) # boolean indexing
1 loops, best of 3: 1.26 s per loop
%timeit
usa eltimeit
módulo incorporado . Échale un vistazo también. docs.python.org/library/timeit.htmlRespuestas:
b = a[a>threshold]
esto debería hacerProbé de la siguiente manera:
import numpy as np, datetime # array of zeros and ones interleaved lrg = np.arange(2).reshape((2,-1)).repeat(1000000,-1).flatten() t0 = datetime.datetime.now() flt = lrg[lrg==0] print datetime.datetime.now() - t0 t0 = datetime.datetime.now() flt = np.array(filter(lambda x:x==0, lrg)) print datetime.datetime.now() - t0
tengo
$ python test.py 0:00:00.028000 0:00:02.461000
http://docs.scipy.org/doc/numpy/user/basics.indexing.html#boolean-or-mask-index-arrays
fuente
np.ma
está destinado a hacer eso, no sé cómo.