python - functions - taquigrafía numpy para tomar rebanada dentada
numpy python 3 (3)
Creo que su método actual es probablemente la mejor manera.
También puede usar choose
para este tipo de selección. Esto es sintácticamente más claro, pero es más complicado acertar y potencialmente más limitado. El equivalente con este método sería:
entries_of_interest.choose(a.T)
Tengo una operación que estoy haciendo comúnmente, a la que llamo una "porción irregular" porque no sé el nombre real para ella. Se explica mejor con el ejemplo:
a = np.random.randn(50, 10)
entries_of_interest = np.random.randint(10, size = 50) # Vector of 50 indices between 0 and 9
# Now I want the values contained in each row of a at the corresponding index in "entries of interest"
jagged_slice_of_a = a[np.arange(a.shape[0]), entries_of_interest]
# jagged_slice_of_a is now a vector with 50 elements. Good.
El único problema es que es un poco engorroso hacer esto a[np.arange(a.shape[0]), entries_of_interest]
(parece una tontería tener que construir el "np.arange (a.shape [0])" solo por el bien de esto). Me gustaría algo como el operador :
para esto, pero el :
hace algo más. ¿Hay alguna forma más concisa de hacer esta operación?
La mejor respuesta:
No, no hay mejor manera con Numpy nativo. Puede crear una función auxiliar para esto si lo desea.
Esto es combersome solamente en el sentido de que requiere más tipeo para una tarea que te parece tan simple.
a[np.arange(a.shape[0]), entries_of_interest]
Pero como nota, el sintácticamente más simple a[:, entries_of_interest]
tiene otra interpretación en numpy
. Elegir un subconjunto de las columnas de una matriz es una tarea más común que elegir un elemento (aleatorio) de cada fila.
Su caso es solo una instancia especializada de
a[I, J]
donde I
y J
son 2 matrices de la misma forma. En el caso general, las entries_of_interest
podrían ser más pequeñas que a.shape[0]
(no todas las filas), o más grandes (varios elementos de algunas filas), o incluso ser 2d. Incluso podría seleccionar ciertos elementos repetidamente.
He encontrado en otras preguntas de SO que la realización de este tipo de selección de elementos es más rápida cuando se aplica a a.flat
. Pero eso requiere algunas matemáticas para construir el tipo de índice plano I*n+J
Con su conocimiento especial de J
, la construcción I
parece un trabajo extra, pero numpy
no puede hacer ese tipo de suposición. Si esta selección fuera más común, alguien podría escribir una función que envuelva tu expresión
def peter_selection(a,I):
# check the a.shape[0]==I.shape[0]
return a[np.arange(a.shape[0]), I]
Los elementos en jagged_slice_of_a
son los elementos diagonales de a[:,entries_of_interest]
Una forma un poco menos engorrosa de hacer esto sería usar np.diagonal
para extraerlos.
jagged_slice_of_a = a[:, entries_of_interest].diagonal()