query objects elemmatch array python arrays numpy

python - objects - Acceda a mĂșltiples elementos de una matriz



mongodb subdocument query (3)

Puedes usar np.choose .

Aquí hay un ejemplo de Array NumPy:

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

Digamos que queremos elegir los valores [1, 2, 3] de la primera fila, [11, 12, 13] de la segunda fila y [17, 18, 19] de la tercera fila.

En otras palabras, seleccionaremos los índices de cada fila de arr como se muestra en una matriz idx :

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

Luego usando np.choose :

>>> np.choose(idx, arr.T[:,:,np.newaxis]) array([[ 1, 2, 3], [11, 12, 13], [17, 18, 19]])

Para explicar lo que acaba de suceder: arr.T[:,:,np.newaxis] significaba que arr se veía temporalmente como una matriz 3D con forma (7, 3, 1) . Puedes imaginar esto como una matriz 3D donde cada columna del arr original ahora es un vector de columna 2D con tres valores. La matriz 3D se parece un poco a esto:

# 0 1 2 3 4 5 6 [[ 0] [[ 1] [[ 2] [[ 3] [[ 4] [[ 5] [[ 6] # choose values from 1, 2, 3 [ 7] [ 8] [ 9] [10] [11] [12] [13] # choose values from 4, 5, 6 [14]] [15]] [16]] [17]] [18]] [19]] [20]] # choose values from 3, 4, 5

Para obtener la fila zeroth de la matriz de salida, seleccione selecciona el elemento zeroth de la columna 2D en el índice 1 , el elemento zeroth de la columna 2D en el índice 2 y el elemento zeroth de la columna 2D en el índice 3 .

Para obtener la primera fila de la matriz de salida, seleccione selecciona el primer elemento de la columna 2D en el índice 4 , el primer elemento de la columna 2D en el índice 5 , ... y así sucesivamente.

¿Hay alguna forma de obtener elementos de matriz en una operación para filas y columnas conocidas de esos elementos? En cada fila me gustaría acceder a los elementos de col_start a col_end (cada fila tiene diferentes índices de inicio y finalización). El número de elementos es el mismo para cada fila, los elementos son consecutivos. Ejemplo:

[ . . . . | | | . . . . . ] [ | | | . . . . . . . . . ] [ . . | | | . . . . . . . ] [ . . . . . . . . | | | . ]

Una solución sería obtener índices (par fila-columna) de elementos y utilizar my_array [row_list, col_list].

¿Hay alguna otra forma (más simple) sin usar para los bucles?


Creo que estás buscando algo como lo siguiente. Sin embargo, no estoy seguro de qué quieres hacer con ellos cuando accedes a ellos.

indexes = [(4,6), (0,2), (2,4), (8, 10)] arr = [ [ . . . . | | | . . . . . ], [ | | | . . . . . . . . . ], [ . . | | | . . . . . . . ], [ . . . . . . . . | | | . ] ] for x in zip(indexes, arr): index = x[0] row = x[1] print row[index[0]:index[1]+1]


A = np.arange(40).reshape(4,10)*.1 startend = [[2,5],[3,6],[4,7],[5,8]] index_list = [np.arange(v[0],v[1]) + i*A.shape[1] for i,v in enumerate(startend)] # [array([2, 3, 4]), array([13, 14, 15]), array([24, 25, 26]), array([35, 36, 37])] A.flat[index_list]

productor

array([[ 0.2, 0.3, 0.4], [ 1.3, 1.4, 1.5], [ 2.4, 2.5, 2.6], [ 3.5, 3.6, 3.7]])

Esto todavía tiene una iteración, pero es bastante básico sobre una lista. Estoy indexando la versión plana, 1d, de A np.take(A, index_list) también funciona.

Si los intervalos de fila difieren en tamaño, puedo usar np.r_ para concatenarlos. No es absolutamente necesario, pero es una ventaja cuando se crean índices a partir de múltiples intervalos y valores.

A.flat[np.r_[tuple(index_list)]] # array([ 0.2, 0.3, 0.4, 1.3, 1.4, 1.5, 2.4, 2.5, 2.6, 3.5, 3.6, 3.7])

El idx que usa el ajcr se puede usar sin choose :

idx = [np.arange(v[0], v[1]) for i,v in enumerate(startend)] A[np.arange(A.shape[0])[:,None], idx]

idx es como mi index_list excepto que no agrega la longitud de la fila.

np.array(idx) array([[2, 3, 4], [3, 4, 5], [4, 5, 6], [5, 6, 7]])

Como cada arange tiene la misma longitud, idx se puede generar sin iteración:

col_start = np.array([2,3,4,5]) idx = col_start[:,None] + np.arange(3)

El primer índice es una matriz de columnas que difunde para que coincida con este idx .

np.arange(A.shape[0])[:,None] array([[0], [1], [2], [3]])

Con esta A e idx obtengo los siguientes tiempos:

In [515]: timeit np.choose(idx,A.T[:,:,None]) 10000 loops, best of 3: 30.8 µs per loop In [516]: timeit A[np.arange(A.shape[0])[:,None],idx] 100000 loops, best of 3: 10.8 µs per loop In [517]: timeit A.flat[idx+np.arange(A.shape[0])[:,None]*A.shape[1]] 10000 loops, best of 3: 24.9 µs per loop

La indexación flat es más rápida, pero calcular el índice más sofisticado toma algo de tiempo.

Para arreglos grandes, domina la velocidad de indexación flat .

A=np.arange(4000).reshape(40,100)*.1 col_start=np.arange(20,60) idx=col_start[:,None]+np.arange(30) In [536]: timeit A[np.arange(A.shape[0])[:,None],idx] 10000 loops, best of 3: 108 µs per loop In [537]: timeit A.flat[idx+np.arange(A.shape[0])[:,None]*A.shape[1]] 10000 loops, best of 3: 59.4 µs per loop

El método np.choose se ejecuta en un límite codificado: Need between 2 and (32) array objects (inclusive).

¿Qué fuera de límites idx ?

col_start=np.array([2,4,6,8]) idx=col_start[:,None]+np.arange(3) A[np.arange(A.shape[0])[:,None], idx]

produce un error porque el último valor de idx es 10 , demasiado grande.

Puede clip idx

idx=idx.clip(0,A.shape[1]-1)

produciendo valores duplicados en la última fila

[ 3.8, 3.9, 3.9]

También puede rellenar A antes de indexar. Ver np.pad para más opciones.

np.pad(A,((0,0),(0,2)),''edge'')[np.arange(A.shape[0])[:,None], idx]

Otra opción es eliminar los valores fuera de límites. idx se convertiría en una lista desigual de listas (o una matriz de listas). El enfoque flat puede manejar esto, aunque el resultado no será una matriz.

startend = [[2,5],[4,7],[6,9],[8,10]] index_list = [np.arange(v[0],v[1]) + i*A.shape[1] for i,v in enumerate(startend)] # [array([2, 3, 4]), array([14, 15, 16]), array([26, 27, 28]), array([38, 39])] A.flat[np.r_[tuple(index_list)]] # array([ 0.2, 0.3, 0.4, 1.4, 1.5, 1.6, 2.6, 2.7, 2.8, 3.8, 3.9])