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 lugar de hacerlo NaN
de una manera fácil.
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 lugar de hacerlo NaN
de una manera fácil.
Respuestas:
Raramente necesita 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 ndarray.fill(..)
como la alternativa más rápida. OTOH, me gusta la implementación de conveniencia de numpy donde puede asignar valores a segmentos enteros 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 numpy.empty((3,3,)).fill(numpy.nan)
lo que en su lugar regresará None
.
a = numpy.empty((3, 3,)) * numpy.nan
. ¡Se cronometró más rápido fill
pero más lento que el método de asignación, pero es una línea!
.fill()
método, pero la diferencia de velocidades se reduce a prácticamente nada a medida que las matrices se hacen más grandes.
np.empty([2, 5])
crea una matriz, luego fill()
modifica esa matriz en el lugar, pero no devuelve una copia o una referencia. Si desea llamar np.empty(2, 5)
por un nombre ("asignar es a una variable"), debe hacerlo antes de realizar operaciones in situ en él. Lo mismo pasa si lo haces [1, 2, 3].insert(1, 4)
. Se crea la lista y se inserta un 4, pero es imposible obtener una referencia a la lista (y, por lo tanto, se puede suponer que se ha recolectado basura). En datos inmutables como cadenas, se devuelve una copia, porque no puede operar en el lugar. Los pandas pueden hacer ambas cosas.
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 puede llenarlo con cualquier otro número que desee.
full
está destinado. np.empy((x,y))*np.nan
es un buen finalista (y compatibilidad para versiones antiguas de numpy).
fill
python -mtimeit "import numpy as np; a = np.empty((100,100));" "a.fill(np.nan)" 100000 loops, best of 3: 13.3 usec per loop python -mtimeit "import numpy as np; a = np.full((100,100), np.nan);" 100000 loops, best of 3: 18.5 usec per loop
python -mtimeit "import numpy as np; a = np.empty((1000,1000)); a.fill(np.nan)" 1000 loops, best of 3: 381 usec per loop $ python -mtimeit "import numpy as np; a = np.full((1000,1000), np.nan);" 1000 loops, best of 3: 383 usec per loop
Comparé las alternativas sugeridas para la velocidad y descubrí que, para vectores / matrices lo suficientemente grandes como para llenar, 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])
perfplot.show(
setup=lambda n: n,
kernels=[fill, colon, full, ones_times, list],
n_range=[2 ** k for k in range(20)],
logx=True,
logy=True,
xlabel="len(a)",
)
numpy.full(n, val)
sea más lento que a = numpy.empty(n) .. a.fill(val)
porque hace lo mismo internamente
¿Estás familiarizado con numpy.nan
?
Puede crear su propio método, como:
def nans(shape, dtype=float):
a = numpy.empty(shape, dtype)
a.fill(numpy.nan)
return a
Luego
nans([3,4])
saldría
array([[ NaN, NaN, NaN, NaN],
[ NaN, NaN, NaN, NaN],
[ NaN, NaN, NaN, NaN]])
Encontré este código en un hilo de la lista de correo .
Siempre puede usar la multiplicación si no recuerda 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 el @ u0b34a0f6ae's respuesta aceptada de es 3 veces más rápida (ciclos de CPU, no ciclos cerebrales para recordar sintaxis numpy;):
$ 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
Otra alternativa es numpy.broadcast_to(val,n)
que regresa en tiempo constante sin importar el tamaño y también es la memoria más eficiente (devuelve una vista del elemento repetido). La advertencia es que el valor devuelto es de solo lectura.
A continuación se muestra una comparación de las actuaciones de todos los otros métodos que se han propuesto utilizando el mismo punto de referencia que en la respuesta de Nico Schlömer .
Como se dijo, numpy.empty () es el camino a seguir. Sin embargo, para los objetos, fill () podría no hacer exactamente lo que cree que hace:
In[36]: a = numpy.empty(5,dtype=object)
In[37]: a.fill([])
In[38]: a
Out[38]: array([[], [], [], [], []], dtype=object)
In[39]: a[0].append(4)
In[40]: a
Out[40]: array([[4], [4], [4], [4], [4]], dtype=object)
Una forma de evitarlo puede ser, por ejemplo:
In[41]: a = numpy.empty(5,dtype=object)
In[42]: a[:]= [ [] for x in range(5)]
In[43]: a[0].append(4)
In[44]: a
Out[44]: array([[4], [], [], [], []], dtype=object)
Otra posibilidad aún no mencionada aquí es usar el mosaico NumPy:
a = numpy.tile(numpy.nan, (3, 3))
También da
array([[ NaN, NaN, NaN],
[ NaN, NaN, NaN],
[ NaN, NaN, NaN]])
No sé sobre la comparación de velocidad.
np.nan
sale mal cuando se convierte a int.