slicing narray multidimensional magic index array python numpy magic-methods

narray - ¿Cómo funciona python numpy.where() work?



python numpy multidimensional array (3)

¿Cómo logran internamente que puedas pasar algo como x> 5 a un método?

La respuesta corta es que no.

Cualquier tipo de operación lógica en una matriz numpy devuelve una matriz booleana. (es decir, __gt__ , __lt__ , etc. todos devuelven matrices booleanas donde la condición dada es verdadera).

P.ej

x = np.arange(9).reshape(3,3) print x > 5

rendimientos:

array([[False, False, False], [False, False, False], [ True, True, True]], dtype=bool)

Esta es la misma razón por la cual algo como if x > 5: levanta un ValueError si x es una matriz numpy. Es una matriz de valores True / False, no un solo valor.

Además, las matrices numeables pueden indexarse ​​mediante matrices booleanas. Por ejemplo, x[x>5] produce [6 7 8] , en este caso.

Honestamente, es bastante raro que realmente necesites numpy.where pero solo devuelve las indices donde una matriz booleana es True . Por lo general, puede hacer lo que necesita con indexación booleana simple.

Estoy jugando con numpy y buscando documentación y me he topado con algo de magia. A saber, estoy hablando de numpy.where() :

>>> x = np.arange(9.).reshape(3, 3) >>> np.where( x > 5 ) (array([2, 2, 2]), array([0, 1, 2]))

¿Cómo logran internamente que puedas pasar algo como x > 5 a un método? Supongo que tiene algo que ver con __gt__ pero estoy buscando una explicación detallada.


np.where devuelve una tupla de longitud igual a la dimensión de nudy ndarray en la que se llama (en otras palabras ndim ) y cada elemento de tupla es una ndarray numpy de índices de todos los valores en la ndarray inicial para la cual la condición es verdad. (No confunda la dimensión con la forma)

Por ejemplo:

x=np.arange(9).reshape(3,3) print(x) array([[0, 1, 2], [3, 4, 5], [6, 7, 8]]) y = np.where(x>4) print(y) array([1, 2, 2, 2], dtype=int64), array([2, 0, 1, 2], dtype=int64))


y es una tupla de longitud 2 porque x.ndim es 2. El primer elemento en la tupla contiene números de fila de todos los elementos mayores que 4 y el segundo elemento contiene números de columna de todos los elementos mayores que 4. Como puede ver, [1, 2,2,2] corresponde a los números de fila de 5,6,7,8 y [2,0,1,2] corresponde a los números de columna de 5,6,7,8. Observe que el ndarray se atraviesa a lo largo de la primera dimensión ( en fila).

Similar,

x=np.arange(27).reshape(3,3,3) np.where(x>4)


devolverá una tupla de longitud 3 porque x tiene 3 dimensiones.

Pero espera, ¡hay más para np.where!

cuando se agregan dos argumentos adicionales a np.where ; hará una operación de reemplazo para todas las combinaciones de fila-columna por parejas que se obtienen mediante la tupla anterior.

x=np.arange(9).reshape(3,3) y = np.where(x>4, 1, 0) print(y) array([[0, 0, 0], [0, 0, 1], [1, 1, 1]])


Old Answer es un poco confuso. Te da las LOCACIONES (todas) de donde tu declaración es verdadera.

asi que:

>>> a = np.arange(100) >>> np.where(a > 30) (array([31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99]),) >>> np.where(a == 90) (array([90]),) a = a*40 >>> np.where(a > 1000) (array([26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99]),) >>> a[25] 1000 >>> a[26] 1040

Lo uso como una alternativa a list.index (), pero también tiene muchos otros usos. Nunca lo he usado con arreglos 2D.

http://docs.scipy.org/doc/numpy/reference/generated/numpy.where.html

Nueva respuesta Parece que la persona estaba pidiendo algo más fundamental.

La pregunta era cómo podría USTED implementar algo que permita que una función (por ejemplo, dónde) sepa lo que se solicitó.

Primero tenga en cuenta que llamar a cualquiera de los operadores de comparación hace algo interesante.

a > 1000 array([False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True`, True, True, True, True, True, True, True, True, True], dtype=bool)`

Esto se hace sobrecargando el método "__gt__". Por ejemplo:

>>> class demo(object): def __gt__(self, item): print item >>> a = demo() >>> a > 4 4

Como puede ver, "a> 4" era un código válido.

Puede obtener una lista completa y la documentación de todas las funciones sobrecargadas aquí: http://docs.python.org/reference/datamodel.html

Algo increíble es lo simple que es hacer esto. TODAS las operaciones en python se hacen de esa manera. Decir a> b es equivalente a a. gt (b)!