Cómo agregar una nueva fila a una matriz vacía vacía


158

Utilizando matrices Python estándar, puedo hacer lo siguiente:

arr = []
arr.append([1,2,3])
arr.append([4,5,6])
# arr is now [[1,2,3],[4,5,6]]

Sin embargo, no puedo hacer lo mismo en numpy. Por ejemplo:

arr = np.array([])
arr = np.append(arr, np.array([1,2,3]))
arr = np.append(arr, np.array([4,5,6]))
# arr is now [1,2,3,4,5,6]

También investigué vstack, pero cuando lo uso vstacken una matriz vacía, obtengo:

ValueError: all the input array dimensions except for the concatenation axis must match exactly

Entonces, ¿cómo agrego una nueva fila a una matriz vacía en numpy?


1
Si está vacío, ¿por qué molestarse? Simplemente comience desde una matriz que contenga solo la primera fila.
jonrsharpe

10
Solo quiero saber si es posible agregar a una matriz vacía vacía. A veces es más limpio escribir código como este ya que las operaciones de agregar están en un bucle.
Tony Stark

55
Dada la forma en que funcionan las matrices numpy, es mucho mejor construir una matriz vacía y luego
ingresar

Respuestas:


227

La forma de "iniciar" la matriz que desea es:

arr = np.empty((0,3), int)

Que es una matriz vacía pero tiene la dimensionalidad adecuada.

>>> arr
array([], shape=(0, 3), dtype=int64)

Luego asegúrese de agregar a lo largo del eje 0:

arr = np.append(arr, np.array([[1,2,3]]), axis=0)
arr = np.append(arr, np.array([[4,5,6]]), axis=0)

Pero @jonrsharpe tiene razón. De hecho, si va a agregar en un bucle, sería mucho más rápido agregar a una lista como en su primer ejemplo, luego convertir a una matriz numpy al final, ya que realmente no está usando numpy como previsto durante el ciclo:

In [210]: %%timeit
   .....: l = []
   .....: for i in xrange(1000):
   .....:     l.append([3*i+1,3*i+2,3*i+3])
   .....: l = np.asarray(l)
   .....: 
1000 loops, best of 3: 1.18 ms per loop

In [211]: %%timeit
   .....: a = np.empty((0,3), int)
   .....: for i in xrange(1000):
   .....:     a = np.append(a, 3*i+np.array([[1,2,3]]), 0)
   .....: 
100 loops, best of 3: 18.5 ms per loop

In [214]: np.allclose(a, l)
Out[214]: True

La forma numpythonic de hacerlo depende de su aplicación, pero sería más como:

In [220]: timeit n = np.arange(1,3001).reshape(1000,3)
100000 loops, best of 3: 5.93 µs per loop

In [221]: np.allclose(a, n)
Out[221]: True

¿Qué pasa si tengo que hacer esto 10 ^ 5 o 10 ^ 6 veces? parece que ninguno de estos métodos se mantendrá. ¿cualquier sugerencia?
Rho Phi

@Roberto, por lo general, hay alguna forma de determinar el tamaño o la forma (al menos, los valores serían preferibles) de la matriz por adelantado. ¿Crees que puedes hacer eso? Anexar realmente debería ser una operación de una o dos veces.
askewchan

a veces no puedes adivinar las dimensiones, es la vida. Sin embargo, puede asignar una matriz lo suficientemente grande y dar valores a sus vistas. Sin embargo, no me gusta, porque hay valores no deseados que uno tiene que encontrar una manera de "enmascarar". Esta idea de enmascarar realmente no se ajusta a mi gusto.
Rho Phi

No es necesario enmascarar, ¡solo córtala! a = a[:N] Aunque creo firmemente que debe encontrar una manera de vectorizarlo (publique una nueva pregunta con sus detalles si necesita ayuda) o simplemente use listas hasta que termine el ciclo.
askewchan

29

Aquí está mi solución:

arr = []
arr.append([1,2,3])
arr.append([4,5,6])
np_arr = np.array(arr)

La matriz resultante tiene un tipo de objeto, que no es aceptable en ciertos casos
zer0fool

26

En este caso, es posible que desee utilizar las funciones np.hstack y np.vstack

arr = np.array([])
arr = np.hstack((arr, np.array([1,2,3])))
# arr is now [1,2,3]

arr = np.vstack((arr, np.array([4,5,6])))
# arr is now [[1,2,3],[4,5,6]]

También puede usar la función np.concatenate.

Salud


77
No funcionará si la segunda matriz tiene dimensión> = 2 como unos ((2, 2)). Me parece que no hay forma de evitar casos límite si está construyendo matrices de vacío por concatenación.
Taozi

No es una buena solución ya que uno necesita verificar la dimensión cada vez.
SKR

1

usando una definición de dtype personalizada, lo que funcionó para mí fue:

import numpy

# define custom dtype
type1 = numpy.dtype([('freq', numpy.float64, 1), ('amplitude', numpy.float64, 1)])
# declare empty array, zero rows but one column
arr = numpy.empty([0,1],dtype=type1)
# store row data, maybe inside a loop
row = numpy.array([(0.0001, 0.002)], dtype=type1)
# append row to the main array
arr = numpy.row_stack((arr, row))
# print values stored in the row 0
print float(arr[0]['freq'])
print float(arr[0]['amplitude'])

1

En caso de agregar nuevas filas para la matriz en bucle, asigne la matriz directamente por primera vez en bucle en lugar de inicializar una matriz vacía.

for i in range(0,len(0,100)):
    SOMECALCULATEDARRAY = .......
    if(i==0):
        finalArrayCollection = SOMECALCULATEDARRAY
    else:
        finalArrayCollection = np.vstack(finalArrayCollection,SOMECALCULATEDARRAY)

Esto es principalmente útil cuando se desconoce la forma de la matriz


0

Quiero hacer un bucle for, pero con el método askewchan no funciona bien, así que lo he modificado.

x=np.empty((0,3))
y=np.array([1 2 3])
for i in ...
x = vstack((x,y))
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.