inicializar una matriz numpy

129

¿Hay alguna forma de inicializar una matriz numpy de una forma y agregarla? Explicaré lo que necesito con un ejemplo de lista. Si quiero crear una lista de objetos generados en un bucle, puedo hacer:

a = []
for i in range(5):
    a.append(i)

Quiero hacer algo similar con una matriz numpy. Sé sobre vstack, concatenate, etc. Sin embargo, parece que estos requieren dos matrices numpy como entradas. Lo que necesito es:

big_array # Initially empty. This is where I don't know what to specify
for i in range(5):
    array i of shape = (2,4) created.
    add to big_array

El big_arraydebería tener una forma (10,4). ¿Como hacer esto?


EDITAR:

Quiero agregar la siguiente aclaración. Soy consciente de que puedo definir big_array = numpy.zeros((10,4))y luego llenarlo. Sin embargo, esto requiere especificar el tamaño de big_array de antemano. Sé el tamaño en este caso, pero ¿y si no lo sé? Cuando usamos la .appendfunción para extender la lista en Python, no necesitamos saber su tamaño final de antemano. Me pregunto si existe algo similar para crear una matriz más grande a partir de matrices más pequeñas, comenzando con una matriz vacía.

Curious2learn
fuente
Por cierto que su primer ejemplo de código se puede escribir de forma clara y sucintamente como una lista por comprensión: [i for i in range(5)]. (Equivalentemente list(range(5)), aunque este es un ejemplo artificial.)
Katriel
¿Qué solución funcionó para usted? Estoy tratando de hacer algo similar como x = numpy.array()lo haríamos con una lista como y = []; pero no funcionó
kRazzy R

Respuestas:

160

numpy.zeros

Devuelve una nueva matriz de formas y tipos dados, llenos de ceros.

o

numpy.ones

Devuelve un nuevo conjunto de formas y tipos dados, rellenos con unos.

o

numpy.empty

Devuelve una nueva matriz de forma y tipo dados, sin inicializar entradas.


Sin embargo, la mentalidad en la que construimos una matriz agregando elementos a una lista no se usa mucho en numpy, porque es menos eficiente (los tipos de datos numpy están mucho más cerca de las matrices C subyacentes). En su lugar, debe preasignar la matriz al tamaño que necesita, y luego completar las filas. Sin numpy.appendembargo, puedes usarlo si es necesario.

Katriel
fuente
2
Sé que puedo configurar big_array = numpy.zeros y luego llenarlo con las pequeñas matrices creadas. Sin embargo, esto requiere que especifique el tamaño de big_array de antemano. ¿No hay nada como .append de la función de lista donde no tengo que especificar el tamaño de antemano? ¡Gracias!
Curious2learn
2
@ Curious2learn. No, no hay nada como agregar en Numpy. Hay funciones que concatenan matrices o las apilan haciendo nuevas matrices, pero no lo hacen agregando. Esto se debe a la forma en que se configuran las estructuras de datos. Las matrices Numpy están hechas para ser rápidas en virtud de poder almacenar valores de forma más compacta, pero deben tener un tamaño fijo para obtener esta velocidad. Las listas de Python están diseñadas para ser más flexibles a costa de la velocidad y el tamaño.
Justin Peel
3
@Curious: bueno, hay una appenden numpy. Es solo que es menos eficiente no preasignar (en este caso, mucho menos eficiente, ya que appending copia la matriz completa cada vez), por lo que no es una técnica estándar.
Katriel
1
¿Qué pasa si solo parte de la np.emptymatriz está llena de valores? ¿Qué pasa con los artículos "vacíos" restantes?
Lee
1
Si sólo conoce sabe la anchura (por ejemplo, necesario para np.concatenate()), puede inicializar con: np.empty((0, some_width)). 0, por lo que su primera matriz no será basura.
NumesSanguis
40

La forma en que generalmente hago eso es creando una lista regular, luego agrego mis cosas en ella y finalmente transformo la lista en una matriz numpy de la siguiente manera:

import numpy as np
big_array = [] #  empty regular list
for i in range(5):
    arr = i*np.ones((2,4)) # for instance
    big_array.append(arr)
big_np_array = np.array(big_array)  # transformed to a numpy array

por supuesto, su objeto final ocupa el doble de espacio en la memoria en el paso de creación, pero agregar en la lista de Python es muy rápido, y la creación usando np.array () también.

mad7777
fuente
11
Sin embargo, este no es el camino a seguir si conoce el tamaño de la matriz con anticipación ... Termino usando este método con frecuencia cuando no sé qué tan grande será la matriz. Por ejemplo, al leer datos de un archivo u otro proceso. No es realmente tan horrible como puede parecer al principio ya que Python y Numpy son bastante inteligentes.
travc
18

Introducido en numpy 1.8:

numpy.full

Devuelve un nuevo conjunto de formas y tipos dados, rellenos con fill_value.

Ejemplos:

>>> import numpy as np
>>> np.full((2, 2), np.inf)
array([[ inf,  inf],
       [ inf,  inf]])
>>> np.full((2, 2), 10)
array([[10, 10],
       [10, 10]])
Franck Dernoncourt
fuente
13

Matriz análoga para el pitón

a = []
for i in range(5):
    a.append(i)

es:

import numpy as np

a = np.empty((0))
for i in range(5):
    a = np.append(a, i)
Adobe
fuente
55
@NicholasTJ: empty((0))inicializa una matriz numpy.
Adobe
2
los corchetes en np.empty ((0)) son redundantes.
Szymon Roziewski
7

numpy.fromiter() es lo que buscas:

big_array = numpy.fromiter(xrange(5), dtype="int")

También funciona con expresiones generadoras, por ejemplo:

big_array = numpy.fromiter( (i*(i+1)/2 for i in xrange(5)), dtype="int" )

Si conoce de antemano la longitud de la matriz, puede especificarla con un argumento opcional de 'conteo'.

Metrópoli cuántica
fuente
2
Realmente ejecuté timeit, y creo que np.fromiter () podría ser más lento que np.array (). timeit ("np.array (i para i en xrange (100))", setup = "import numpy as np", number = 10000) -> 0.02539992332458496, versus timeit ("np.fromiter ((i para i en xrange ( 100)), dtype = int) ", setup =" import numpy as np ", number = 10000) -> 0.13351011276245117
hlin117
6

Desea evitar los bucles explícitos tanto como sea posible al hacer la computación en matriz, ya que eso reduce la ganancia de velocidad de esa forma de computación. Hay varias formas de inicializar una matriz numpy. Si quieres que esté lleno de ceros, haz lo que dijo katrielalex:

big_array = numpy.zeros((10,4))

EDITAR: ¿Qué tipo de secuencia estás haciendo? Debe consultar las diferentes funciones numpy que crean matrices, como numpy.linspace(start, stop, size)(número igualmente espaciado) o numpy.arange(start, stop, inc). Donde sea posible, estas funciones harán que los arreglos sean sustancialmente más rápidos que hacer el mismo trabajo en bucles explícitos

Andreas Løve Selvik
fuente
5

Para su primer ejemplo de matriz use,

a = numpy.arange(5)

Para inicializar big_array, use

big_array = numpy.zeros((10,4))

Esto supone que desea inicializar con ceros, lo cual es bastante típico, pero hay muchas otras formas de inicializar una matriz en numpy .

Editar: si no conoce el tamaño de big_array de antemano, generalmente es mejor construir primero una lista de Python usando append, y cuando tenga todo recogido en la lista, convierta esta lista en una matriz numpy usando numpy.array(mylist). La razón de esto es que las listas están destinadas a crecer de manera muy eficiente y rápida, mientras que numpy.concatenate sería muy ineficiente ya que las matrices numpy no cambian de tamaño fácilmente. Pero una vez que todo se recopila en una lista, y conoce el tamaño final de la matriz, se puede construir una matriz numpy de manera eficiente.

tom10
fuente
5

Para inicializar una matriz numpy con una matriz específica:

import numpy as np

mat = np.array([[1, 1, 0, 0, 0],
                [0, 1, 0, 0, 1],
                [1, 0, 0, 1, 1],
                [0, 0, 0, 0, 0],
                [1, 0, 1, 0, 1]])

print mat.shape
print mat

salida:

(5, 5)
[[1 1 0 0 0]
 [0 1 0 0 1]
 [1 0 0 1 1]
 [0 0 0 0 0]
 [1 0 1 0 1]]
edW
fuente
3

Siempre que se encuentre en la siguiente situación:

a = []
for i in range(5):
    a.append(i)

y desea algo similar en numpy, varias respuestas anteriores han señalado formas de hacerlo, pero como señaló @katrielalex, estos métodos no son eficientes. La manera eficiente de hacer esto es crear una lista larga y luego volver a darle la forma que desee después de tener una lista larga. Por ejemplo, digamos que estoy leyendo algunas líneas de un archivo y cada fila tiene una lista de números y quiero construir una matriz de forma numpy (número de líneas leídas, longitud del vector en cada fila). Así es como lo haría de manera más eficiente:

long_list = []
counter = 0
with open('filename', 'r') as f:
    for row in f:
        row_list = row.split()
        long_list.extend(row_list)
        counter++
#  now we have a long list and we are ready to reshape
result = np.array(long_list).reshape(counter, len(row_list)) #  desired numpy array
Heapify
fuente
2

Me doy cuenta de que esto es un poco tarde, pero no noté ninguna de las otras respuestas que mencionan la indexación en la matriz vacía:

big_array = numpy.empty(10, 4)
for i in range(5):
    array_i = numpy.random.random(2, 4)
    big_array[2 * i:2 * (i + 1), :] = array_i

De esta manera, preasigna toda la matriz de resultados con numpy.emptyy completa las filas a medida que avanza utilizando la asignación indexada.

Es perfectamente seguro preasignar en emptylugar de zerosen el ejemplo que dio, ya que garantiza que todo el conjunto se llenará con los fragmentos que genere.

Físico loco
fuente
2

Sugeriría definir la forma primero. Luego itere sobre él para insertar valores.

big_array= np.zeros(shape = ( 6, 2 ))
for it in range(6):
    big_array[it] = (it,it) # For example

>>>big_array

array([[ 0.,  0.],
       [ 1.,  1.],
       [ 2.,  2.],
       [ 3.,  3.],
       [ 4.,  4.],
       [ 5.,  5.]])
GT GT
fuente
1

Tal vez algo como esto se ajuste a tus necesidades.

import numpy as np

N = 5
res = []

for i in range(N):
    res.append(np.cumsum(np.ones(shape=(2,4))))

res = np.array(res).reshape((10, 4))
print(res)

Que produce el siguiente resultado

[[ 1.  2.  3.  4.]
 [ 5.  6.  7.  8.]
 [ 1.  2.  3.  4.]
 [ 5.  6.  7.  8.]
 [ 1.  2.  3.  4.]
 [ 5.  6.  7.  8.]
 [ 1.  2.  3.  4.]
 [ 5.  6.  7.  8.]
 [ 1.  2.  3.  4.]
 [ 5.  6.  7.  8.]]

fuente