2009-11-10 8 views
101

I tienen el siguiente código:Inicialización de matriz numpy a algo distinto de cero o uno

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

Se crea una altura x 9 matriz anchura x llenado con ceros. En cambio, me gustaría saber si hay una función o una forma de inicializarlos en vez de NaN.

¿Hay alguno? Sin tener que recurrir a hacer bucles de forma manual y tal?

Gracias

+2

Una advertencia es que NumPy no tiene un valor NA entero (a diferencia de R). Ver [lista de pandas de gotchas] (http://pandas.pydata.org/pandas-docs/stable/gotchas.html). Por lo tanto 'np.nan' sale mal cuando se convierte a int. – smci

+0

smci tiene razón. Para NumPy no hay tal valor de NaN. Entonces depende del tipo y en NumPy qué valor estará allí para NaN. Si no está enterado de esto, causará problemas – Ralf

Respuesta

152

Rara vez se necesitan bucles para operaciones vectoriales en numpy. Puede crear una matriz sin inicializar y asignar 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) tal como fue anunciado 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 horarios muestran una preferencia por ndarray.fill(..) como la alternativa más rápida. OTOH, me gusta la implementación de conveniencia de Numpy, donde puedes asignar valores a rebanadas enteras en el momento, la intención del código es muy clara.

+2

Acepto que la intención de su código es más clara. Pero gracias por los horarios imparciales (o más bien, el hecho de que todavía los hayas publicado), lo agradezco :) –

+2

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

+2

Mire esta respuesta: http://stackoverflow.com/questions/10871220/making-a-matrix-square-and-padding-it-with-desired-value-in-numpy – Ivan

23

Conoce usted numpy.nan?

usted puede crear su propio método, tales como:

def nans(shape, dtype=float): 
    a = numpy.empty(shape, dtype) 
    a.fill(numpy.nan) 
    return a 

Entonces

nans([3,4]) 

habría salida

array([[ NaN, NaN, NaN, NaN], 
     [ NaN, NaN, NaN, NaN], 
     [ NaN, NaN, NaN, NaN]]) 

me encontré con este código en un mailing list thread.

+1

Parece exagerado. –

83

Otra opción es utilizar numpy.full, una opción disponible en NumPy 1.8+

a = np.full([height, width, 9], np.nan) 

Esto es bastante flexible y se puede rellenar con cualquier otro número que desea.

+1

esto es más o menos tan rápido como la respuesta aceptada. – dbliss

+8

Consideraría esto como la * respuesta más correcta * ya que es exactamente para lo que está 'lleno'. 'np.empy ((x, y)) * np.nan' es un buen finalista (y compatibilidad con versiones antiguas de numpy). – travc

+0

esto es más lento que 'fill' ' '' python -mtimeit "import numpy as np; a = np.empty ((100,100));" "a.fill (np.nan)" 100000 loops, mejor de 3: 13.3 usec por ciclo python -mtimeit "import numpy as np; a = np.full ((100,100), np.nan);" 100000 loops, lo mejor de 3: 18.5 usec por loop''' – Farnabaz

10

Siempre se puede usar la multiplicación si no se retiren inmediatamente los .empty o .full métodos:

>>> np.nan * np.ones(shape=(3,2)) 
array([[ nan, nan], 
     [ nan, nan], 
     [ nan, nan]]) 

Por supuesto, funciona con cualquier otro valor numérico así:

>>> 42 * np.ones(shape=(3,2)) 
array([[ 42, 42], 
     [ 42, 42], 
     [ 42, 42]]) 

Pero el @ u0b34a0f6ae's accepted answer es 3 veces más rápido (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 
4

Como dije, numpy.empty() es el camino a seguir.Sin embargo, para los objetos, llenar() podría no hacer exactamente lo que usted cree:

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 evitar 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) 
+0

Además de no tener prácticamente nada que ver con la pregunta original, ordenado. –

+0

Bueno, se trata de "Inicializar la matriz numpy a algo distinto de cero o uno", en el caso "algo otro" es un objeto :) (Más prácticamente, google me llevó aquí para inicializar con una lista vacía) – ntg

15

comparé las alternativas sugeridas para la velocidad y encontró que, para rellenar vectores/matrices suficientemente grandes, todas las alternativas excepto val * ones y array(n * [val]) son igualmente rápidas.

enter image description here


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)' 
    ) 
0

Sin embargo, otra posibilidad todavía no se ha mencionado aquí es el uso de NumPy baldosas:

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.

Cuestiones relacionadas