que - matrices en python numpy
Dividir matriz NumPy según los valores de la matriz(una condición) (3)
Tengo una matriz:
arr = [(1,1,1), (1,1,2), (1,1,3), (1,1,4)...(35,1,22),(35,1,23)]
Quiero dividir mi matriz de acuerdo con el tercer valor en cada par ordenado. Quiero que cada tercer valor de 1 sea el comienzo de una nueva matriz. Los resultados deberían ser:
[(1,1,1), (1,1,2),...(1,1,35)][(1,2,1), (1,2,2),...(1,2,46)]
y así. Sé numpy.split debería hacer el truco, pero estoy perdido en cuanto a cómo escribir la condición para la división.
Al mirar la documentación , parece que especificar el índice de dónde dividir funcionará mejor. Para su ejemplo específico, los siguientes trabajos si arr ya es una matriz numpy bidimensional:
np.split(arr, np.where(arr[:,2] == 1)[0])
arr[:,2]
devuelve una lista de la 3ª entrada en cada tupla. El colon dice que tome cada fila y el 2 dice que tome la tercera columna, que es el 3er componente.
Luego usamos np.where
para devolver todos los lugares donde la tercera coordenada es un 1. Tenemos que hacer np.where()[0]
para acceder directamente a la matriz de ubicaciones.
Luego, conectamos los índices que encontramos donde la tercera coordenada es 1 a np.split que se divide en las ubicaciones deseadas.
Tenga en cuenta que debido a que la primera entrada tiene un 1 en la tercera coordenada, se dividirá antes de la primera entrada. Esto nos da una matriz extra "dividida" que está vacía.
Aquí hay una idea rápida, trabajando con una matriz 1d. Se puede extender fácilmente para que funcione con su matriz 2d:
In [385]: x=np.arange(10)
In [386]: I=np.where(x%3==0)
In [387]: I
Out[387]: (array([0, 3, 6, 9]),)
In [389]: np.split(x,I[0])
Out[389]:
[array([], dtype=float64),
array([0, 1, 2]),
array([3, 4, 5]),
array([6, 7, 8]),
array([9])]
La clave es usar where
encontrar las indecencias en las que desea que se split
.
Para un 2d arr
Primero haz una muestra de 2d array, con algo interesante en la tercera columna:
In [390]: arr=np.ones((10,3))
In [391]: arr[:,2]=np.arange(10)
In [392]: arr
Out[392]:
array([[ 1., 1., 0.],
[ 1., 1., 1.],
...
[ 1., 1., 9.]])
A continuación, use el mismo where
y boolean para buscar índices para dividir:
In [393]: I=np.where(arr[:,2]%3==0)
In [395]: np.split(arr,I[0])
Out[395]:
[array([], dtype=float64),
array([[ 1., 1., 0.],
[ 1., 1., 1.],
[ 1., 1., 2.]]),
array([[ 1., 1., 3.],
[ 1., 1., 4.],
[ 1., 1., 5.]]),
array([[ 1., 1., 6.],
[ 1., 1., 7.],
[ 1., 1., 8.]]),
array([[ 1., 1., 9.]])]
No puedo pensar en ninguna función numpy
o trucos para hacer esto. Una solución simple usando for loop sería:
In [48]: arr = [(1,1,1), (1,1,2), (1,1,3), (1,1,4),(1,2,1),(1,2,2),(1,2,3),(1,3,1),(1,3,2),(1,3,3),(1,3,4),(1,3,5)]
In [49]: result = []
In [50]: for i in arr:
....: if i[2] == 1:
....: tempres = []
....: result.append(tempres)
....: tempres.append(i)
....:
In [51]: result
Out[51]:
[[(1, 1, 1), (1, 1, 2), (1, 1, 3), (1, 1, 4)],
[(1, 2, 1), (1, 2, 2), (1, 2, 3)],
[(1, 3, 1), (1, 3, 2), (1, 3, 3), (1, 3, 4), (1, 3, 5)]]