2010-01-21 36 views
6

Estoy intentando seleccionar elementos de columna específicos para cada fila de una matriz numpy. Por ejemplo, en el siguiente ejemplo:Seleccionar una columna específica en cada fila de la matriz

In [1]: a = np.random.random((3,2)) 
Out[1]: 
array([[ 0.75670668, 0.1283942 ], 
     [ 0.51326555, 0.59378083], 
     [ 0.03219789, 0.53612603]]) 

me gustaría seleccionar el primer elemento de la primera fila, el segundo elemento de la segunda fila, y el primer elemento de la tercera fila. Así que traté de hacer lo siguiente:

In [2]: b = np.array([0,1,0]) 

In [3]: a[:,b] 

Pero esto produce el siguiente resultado:

Out[3]: 
array([[ 0.75670668, 0.1283942 , 0.75670668], 
     [ 0.51326555, 0.59378083, 0.51326555], 
     [ 0.03219789, 0.53612603, 0.03219789]]) 

que claramente no es lo que busco. ¿Hay una manera fácil de hacer lo que me gustaría hacer sin usar los bucles?

Respuesta

8

Se puede utilizar:

a[np.arange(3), (0,1,0)] 

en su ejemplo anterior.

+0

De hecho. * Slicing * conserva el eje dado tal como está, mientras que lo que quería en ambas dimensiones se llama * indexación de fantasía * en la documentación. – dwf

+0

Derecha. Por ejemplo, 'a [0: 2,0: 2]' y 'a [[0,1], [0,1]]' devuelven cosas diferentes. –

2

Esto no es tanto una respuesta como un intento de documentar esto un poco. Para la respuesta anterior, tendríamos:

>>> import numpy as np 
>>> A = np.array(range(6)) 
>>> A 
array([0, 1, 2, 3, 4, 5]) 
>>> A.shape = (3,2) 
>>> A 
array([[0, 1], 
     [2, 3], 
     [4, 5]]) 
>>> A[(0,1,2),(0,1,0)] 
array([0, 3, 4]) 

Especificación de una lista (o tupla) de fila individual y coordina la columna permite la indexación de fantasía de la matriz. El primer ejemplo en el comentario parece similar al principio, pero los índices son porciones. Ellos no se extienden sobre toda la gama, y ​​la forma de la matriz que se devuelve es diferente:

>>> A[0:2,0:2] 
array([[0, 1], 
     [2, 3]]) 

Para el segundo ejemplo en el comentario

>>> A[[0,1],[0,1]] 
array([0, 3]) 

lo que parece que las rebanadas son diferentes, pero a excepción de eso, independientemente de cómo se construyan los índices, puede especificar una tupla o lista de (valores x, valores y) y recuperar esos elementos específicos de la matriz.

3

bien, sólo para aclarar aquí, vamos a hacer un ejemplo sencillo

A=diag(arange(0,10,1)) 

da

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

continuación

A[0][0:4] 

da

array([0, 0, 0, 0]) 

que es primera fila, elementos de 0 a 3. Pero

A[0:4][1] 

no da las primeras 4 filas, el segundo elemento en cada uno. En su lugar obtenemos

array([0, 1, 0, 0, 0, 0, 0, 0, 0, 0]) 

es decir, toda la segunda columna.

A[0:4,1] 

da

array([0, 1, 0, 0]) 

Estoy seguro de que hay una muy buena razón para ello, y que tiene mucho sentido para los programadores pero para aquellos de nosotros no iniciados en esa gran religión que puede ser muy confuso .

+0

A [0: 4] crea una nueva matriz de formas (4,10). Con A [0: 4, y], está pidiendo la segunda dimensión de la matriz, mientras que para A [0: 4] [x], ¡está pidiendo la primera dimensión de la nueva matriz! Puedes escribirlo A [0: 4,:] [1 ,:] si te ayuda a ver cuándo estás pidiendo dim 1 o dim 2 – bendaizer

+0

Usar diag terminó haciendo esto más confuso para ti y para los demás, porque en realidad 'A [ 0: 4] [1] 'le dio la segunda * fila *, no la segunda columna. –

Cuestiones relacionadas