2009-05-18 15 views
35

que tienen una matriz 2D que tiene este aspecto:¿Cuál es la forma más sencilla de extender una matriz numpy en 2 dimensiones?

XX 
xx 

¿Cuál es la forma más eficaz de añadir una fila extra y la columna:

xxy 
xxy 
yyy 

Para los puntos de bonificación, me gustaría ser también capaz de noquear filas y columnas, así que por ejemplo en la matriz de abajo me gustaría poder eliminar todas las a's dejando solo las x, específicamente estoy tratando de eliminar la enésima fila y la enésima columna en al mismo tiempo, y quiero poder hacerlo lo más rápido posible:

xxaxx 
xxaxx 
aaaaa 
xxaxx 
xxaxx 

Respuesta

43

El más corto en términos de líneas de código que puedo pensar es para la primera pregunta.

>>> import numpy as np 
>>> p = np.array([[1,2],[3,4]]) 

>>> p = np.append(p, [[5,6]], 0) 
>>> p = np.append(p, [[7],[8],[9]],1) 

>>> p 
array([[1, 2, 7], 
    [3, 4, 8], 
    [5, 6, 9]]) 

Y el de la segunda pregunta

p = np.array(range(20)) 
>>> p.shape = (4,5) 
>>> p 
array([[ 0, 1, 2, 3, 4], 
     [ 5, 6, 7, 8, 9], 
     [10, 11, 12, 13, 14], 
     [15, 16, 17, 18, 19]]) 
>>> n = 2 
>>> p = np.append(p[:n],p[n+1:],0) 
>>> p = np.append(p[...,:n],p[...,n+1:],1) 
>>> p 
array([[ 0, 1, 3, 4], 
     [ 5, 6, 8, 9], 
     [15, 16, 18, 19]]) 
+0

'np.append' es una de las funciones más abusadas en' numpy'. La mayoría de las veces la gente asume que es como la lista adjunta. Si debe unir matrices, aprenda a usar 'np.concatenate' directamente (incluso si es exigente con las dimensiones y las formas). – hpaulj

33

Una respuesta alternativa útil a la primera pregunta, utilizando los ejemplos de respuesta de tomeedee, sería el uso de numpy vstack y column_stack métodos:

Dada una matriz p,

>>> import numpy as np 
>>> p = np.array([ [1,2] , [3,4] ]) 

una matriz aumentada se puede generar por:

>>> p = np.vstack([ p , [5 , 6] ]) 
>>> p = np.column_stack([ p , [ 7 , 8 , 9 ] ]) 
>>> p 
array([[1, 2, 7], 
     [3, 4, 8], 
     [5, 6, 9]]) 

Estos métodos pueden ser convenientes en la práctica que np.append() ya que permiten matrices de 1D que se añadirán a una matriz sin ninguna modificación, en contraste con la situación siguiente:

>>> p = np.array([ [ 1 , 2 ] , [ 3 , 4 ] , [ 5 , 6 ] ]) 
>>> p = np.append(p , [ 7 , 8 , 9 ] , 1) 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
    File "/usr/lib/python2.6/dist-packages/numpy/lib/function_base.py", line 3234, in append 
    return concatenate((arr, values), axis=axis) 
ValueError: arrays must have same number of dimensions 

En respuesta a la segunda pregunta, una buena manera de eliminar filas y columnas es utilizar lógica array indexación como sigue:

Dada una matriz p,

>>> p = np.arange(20).reshape((4 , 5)) 

Supongamos que queremos eliminar la fila 1 y la columna 2:

>>> r , c = 1 , 2 
>>> p = p [ np.arange(p.shape[0]) != r , : ] 
>>> p = p [ : , np.arange(p.shape[1]) != c ] 
>>> p 
array([[ 0, 1, 3, 4], 
     [10, 11, 13, 14], 
     [15, 16, 18, 19]]) 

Nota - para los usuarios de MATLAB reformados - si se quería hacer esto en una sola línea que necesita para indexar dos veces:

>>> p = np.arange(20).reshape((4 , 5))  
>>> p = p [ np.arange(p.shape[0]) != r , : ] [ : , np.arange(p.shape[1]) != c ] 

Esta técnica también se puede extender para eliminar conjuntos de filas y columnas, así que si queríamos eliminar filas 0 & 2 y las columnas 1, 2 & 3 podríamos utilizar de numpy setdiff1d función para generar el índice lógico deseado:

>>> p = np.arange(20).reshape((4 , 5)) 
>>> r = [ 0 , 2 ] 
>>> c = [ 1 , 2 , 3 ] 
>>> p = p [ np.setdiff1d(np.arange(p.shape[0]), r) , : ] 
>>> p = p [ : , np.setdiff1d(np.arange(p.shape[1]) , c) ] 
>>> p 
array([[ 5, 9], 
     [15, 19]]) 
4

Me resulta mucho más fácil de "extender" a través de la asignación en una matriz más grande. P.ej.

import numpy as np 
p = np.array([[1,2], [3,4]]) 
g = np.array(range(20)) 
g.shape = (4,5) 
g[0:2, 0:2] = p 

Aquí son los arrays:

p

array([[1, 2], 
     [3, 4]]) 

g:

array([[ 0, 1, 2, 3, 4], 
     [ 5, 6, 7, 8, 9], 
     [10, 11, 12, 13, 14], 
     [15, 16, 17, 18, 19]]) 

y la g resultante después de la asignación:

array([[ 1, 2, 2, 3, 4], 
     [ 3, 4, 7, 8, 9], 
     [10, 11, 12, 13, 14], 
     [15, 16, 17, 18, 19]]) 
0

quizás necesite esto.

>>> x = np.array([11,22]) 
>>> y = np.array([18,7,6]) 
>>> z = np.array([1,3,5]) 
>>> np.concatenate((x,y,z)) 
array([11, 22, 18, 7, 6, 1, 3, 5]) 
7

Otra solución elegante al primera pregunta puede ser el comando insert:

p = np.array([[1,2],[3,4]]) 
p = np.insert(p, 2, values=0, axis=1) # insert values before column 2 

provoque:

array([[1, 2, 0], 
     [3, 4, 0]]) 

insert puede ser más lento que append pero le permite llenar toda la fila/columna con un valor fácilmente.

En cuanto a la segunda pregunta, delete ha sugerido antes:

p = np.delete(p, 2, axis=1) 

que restaura la matriz original de nuevo:

array([[1, 2], 
     [3, 4]]) 
1

que puede utilizar:

>>> np.concatenate([array1, array2, ...]) 

p.ej

>>> import numpy as np 
>>> a = [[1, 2, 3],[10, 20, 30]] 
>>> b = [[100,200,300]] 
>>> a = np.array(a) # not necessary, but numpy objects prefered to built-in 
>>> b = np.array(b) # "^ 
>>> a 
array([[ 1, 2, 3], 
     [10, 20, 30]]) 
>>> b 
array([[100, 200, 300]]) 
>>> c = np.concatenate([a,b]) 
>>> c 
array([[ 1, 2, 3], 
     [ 10, 20, 30], 
     [100, 200, 300]]) 
>>> print c 
[[ 1 2 3] 
[ 10 20 30] 
[100 200 300]] 

~ - + - ~ - + - ~ - + - ~

A veces, se encontrará con problemas si un objeto de matriz numpy se inicializa con valores incompletos para su propiedad de forma. Este problema se soluciona asignando a la propiedad de forma la tupla: (array_length, element_length).

Nota: Aquí, 'array_length' y 'element_length' son parámetros enteros, en los que se sustituyen los valores. Una 'tupla' es solo un par de números entre paréntesis.

p. Ej.

>>> import numpy as np 
>>> a = np.array([[1,2,3],[10,20,30]]) 
>>> b = np.array([100,200,300]) # initialize b with incorrect dimensions 
>>> a.shape 
(2, 3) 
>>> b.shape 
(3,) 
>>> c = np.concatenate([a,b]) 

Traceback (most recent call last): 
    File "<pyshell#191>", line 1, in <module> 
    c = np.concatenate([a,b]) 
ValueError: all the input arrays must have same number of dimensions 
>>> b.shape = (1,3) 
>>> c = np.concatenate([a,b]) 
>>> c 
array([[ 1, 2, 3], 
     [ 10, 20, 30], 
     [100, 200, 300]]) 
Cuestiones relacionadas