Cree una matriz numerosa llena de NaN
Tengo el siguiente código:
r = numpy.zeros(shape = (width, height, 9))
Crea una width x height x 9
matriz llena de ceros. En cambio, me gustaría saber si hay una función o forma de inicializarlos en NaN
s de una manera sencilla.
Rara vez necesitas bucles para operaciones vectoriales en numpy. Puede crear una matriz no inicializada y asignarla a todas las entradas a la vez:
>>> a = numpy.empty((3,3,))
>>> a[:] = numpy.nan
>>> a
array([[ NaN, NaN, NaN],
[ NaN, NaN, NaN],
[ NaN, NaN, NaN]])
He cronometrado las alternativas a[:] = numpy.nan
aquí y a.fill(numpy.nan)
según lo publicado por Blaenk:
$ python -mtimeit "import numpy as np; a = np.empty((100,100));" "a.fill(np.nan)"
10000 loops, best of 3: 54.3 usec per loop
$ python -mtimeit "import numpy as np; a = np.empty((100,100));" "a[:] = np.nan"
10000 loops, best of 3: 88.8 usec per loop
Los tiempos muestran una preferencia por ndarray.fill(..)
ser la alternativa más rápida. OTOH, me gusta la implementación conveniente de numpy donde puedes asignar valores a porciones enteras en ese momento, la intención del código es muy clara.
Tenga en cuenta que ndarray.fill
realiza su operación en el lugar, por lo que numpy.empty((3,3,)).fill(numpy.nan)
en su lugar devolverá None
.
Otra opción es usar numpy.full
, una opción disponible en NumPy 1.8+
a = np.full([height, width, 9], np.nan)
Esto es bastante flexible y puedes completarlo con cualquier otro número que desees.
Comparé las alternativas sugeridas en cuanto a velocidad y descubrí que, para vectores/matrices lo suficientemente grandes como para llenarse, todas las alternativas excepto val * ones
y array(n * [val])
son igualmente rápidas.
Código para reproducir la trama:
import numpy
import perfplot
val = 42.0
def fill(n):
a = numpy.empty(n)
a.fill(val)
return a
def colon(n):
a = numpy.empty(n)
a[:] = val
return a
def full(n):
return numpy.full(n, val)
def ones_times(n):
return val * numpy.ones(n)
def list(n):
return numpy.array(n * [val])
b = perfplot.bench(
setup=lambda n: n,
kernels=[fill, colon, full, ones_times, list],
n_range=[2 ** k for k in range(20)],
xlabel="len(a)",
)
b.save("out.png")
Estás familiarizado con numpy.nan
?
Puedes crear tu propio método como:
def nans(shape, dtype=float):
a = numpy.empty(shape, dtype)
a.fill(numpy.nan)
return a
Entonces
nans([3,4])
daría salida
array([[ NaN, NaN, NaN, NaN],
[ NaN, NaN, NaN, NaN],
[ NaN, NaN, NaN, NaN]])
Encontré este código en un hilo de una lista de correo .
Siempre puedes usar la multiplicación si no recuerdas inmediatamente los métodos .empty
o .full
:
>>> np.nan * np.ones(shape=(3,2))
array([[ nan, nan],
[ nan, nan],
[ nan, nan]])
Por supuesto, también funciona con cualquier otro valor numérico:
>>> 42 * np.ones(shape=(3,2))
array([[ 42, 42],
[ 42, 42],
[ 42, 42]])
Pero la respuesta aceptada por @ u0b34a0f6ae es 3 veces más rápida (ciclos de CPU, no ciclos cerebrales para recordar una sintaxis compleja;):
$ python -mtimeit "import numpy as np; X = np.empty((100,100));" "X[:] = np.nan;"
100000 loops, best of 3: 8.9 usec per loop
(predict)laneh@predict:~/src/predict/predict/webapp$ master
$ python -mtimeit "import numpy as np; X = np.ones((100,100));" "X *= np.nan;"
10000 loops, best of 3: 24.9 usec per loop