Cree una matriz numerosa llena de NaN

Resuelto devoured elysium asked hace 14 años • 11 respuestas

Tengo el siguiente código:

r = numpy.zeros(shape = (width, height, 9))

Crea una width x height x 9matriz llena de ceros. En cambio, me gustaría saber si hay una función o forma de inicializarlos en NaNs de una manera sencilla.

devoured elysium avatar Nov 10 '09 07:11 devoured elysium
Aceptado

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.nanaquí 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.fillrealiza su operación en el lugar, por lo que numpy.empty((3,3,)).fill(numpy.nan)en su lugar devolverá None.

u0b34a0f6ae avatar Nov 10 '2009 00:11 u0b34a0f6ae

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.

Pietro Biroli avatar Oct 09 '2014 23:10 Pietro Biroli

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 * onesy array(n * [val])son igualmente rápidas.

ingrese la descripción de la imagen aquí


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")
Nico Schlömer avatar Jul 10 '2017 08:07 Nico Schlömer

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 .

Jorge Israel Peña avatar Nov 10 '2009 00:11 Jorge Israel Peña

Siempre puedes usar la multiplicación si no recuerdas inmediatamente los métodos .emptyo .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
hobs avatar Dec 31 '2014 19:12 hobs