Tengo el siguiente código:
r = numpy.zeros(shape = (width, height, 9))
Crea un 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 NaN
s de una manera fácil.
elíseo devorado
Tengo el siguiente código:
r = numpy.zeros(shape = (width, height, 9))
Crea un 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 NaN
s de una manera fácil.
u0b34a0f6ae
Rara vez 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 por ndarray.fill(..)
como la alternativa más rápida. OTOH, me gusta la implementación conveniente de numpy donde puede asignar valores a segmentos completos 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 cambio, regresará None
.
Estoy de acuerdo en que la intención de su código es más clara. Pero gracias por los tiempos imparciales (o más bien, el hecho de que todavía los publicaste), lo aprecio 🙂
–Jorge Israel Peña
10 de noviembre de 2009 a las 7:19
Me gusta este: a = numpy.empty((3, 3,)) * numpy.nan
. Temporizó más rápido que fill
pero más lento que el método de asignación, ¡pero es un oneliner!
– Heltonbiker
30 de abril de 2012 a las 14:09
Mire esta respuesta: stackoverflow.com/questions/10871220/…
– Iván
3 de junio de 2012 a las 15:15
Prefiero el .fill()
método, pero la diferencia de velocidades se reduce a prácticamente nada a medida que las matrices se hacen más grandes.
– nada101
24 de marzo de 2014 a las 11:13
… porque np.empty([2, 5])
crea una matriz, entonces fill()
modifica esa matriz en el lugar, pero no devuelve una copia o una referencia. si quieres llamar np.empty(2, 5)
por un nombre (“asignar es a una variable”), debe hacerlo antes de realizar operaciones en el lugar. Lo mismo sucede 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.
– monstruo de la flauta7
2 jun 2016 a las 21:26
pietro biroli
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.
Yo consideraría esto como el más correcto respuesta ya que es exactamente lo que full
está destinado a. np.empy((x,y))*np.nan
es un buen subcampeón (y compatibilidad con versiones anteriores de numpy).
– travc
21/09/2015 a las 19:38
esto es mas lento que 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
– Farnabaz
19 oct 2016 a las 13:29
@Farnabaz Si coloca el código equivalente dentro del ciclo de tiempo, son casi iguales. Los dos métodos son básicamente iguales, solo tiene el “np.empty” fuera del temporizador en el primero. 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
–Scott Staniewicz
28 de octubre de 2018 a las 1:35
Nico Schlömer
Comparé las alternativas sugeridas para la velocidad y encontré que, para vectores/matrices suficientemente grandes para llenar, todas las alternativas excepto val * ones
y array(n * [val])
son igualmente rápidos.
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")
extraño que numpy.full(n, val)
es más lento que a = numpy.empty(n) .. a.fill(val)
ya que hace lo mismo internamente
– endolito
3 de agosto de 2019 a las 17:38
Jorge Israel Peña
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
Después
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 la lista de correo.
placas
Siempre puedes usar la multiplicación si no recuerdas inmediatamente el .empty
o .full
métodos:
>>> 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 de @ u0b34a0f6ae es 3 veces más rápida (ciclos de CPU, no ciclos cerebrales para recordar la 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)[email protected]:~/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
físico loco
Como se dijo, numpy.empty() es el camino a seguir. Sin embargo, para los objetos, fill() podría no hacer exactamente lo que crees 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)
JHBonarius
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é acerca de la comparación de velocidad.
Una advertencia es que NumPy no tiene un valor NA entero (a diferencia de R). Ver pandas lista de trampas. Por eso
np.nan
sale mal cuando se convierte a int.– smci
28 de julio de 2013 a las 3:31
smci tiene razón. Para NumPy no existe tal valor de NaN. Entonces, depende del tipo y de NumPy qué valor estará allí para NaN. Si no es consciente de esto, le causará problemas.
– Programa de control maestro
4 de noviembre de 2016 a las 15:38
De hecho, parecería que hay margen para que una función np.nans imite np.zeros y np.ones, pero supongo que np.full es una generalización que excluye la necesidad de todas las funciones especializadas. Buena pregunta.
– Adrián Tompkins
21 de enero a las 11:25