Quiero modificar una matriz de transición cuadrada densa en el lugar cambiando el orden de varias de sus filas y columnas, usando la biblioteca numpy de python. Matemáticamente, esto corresponde a la multiplicación previa de la matriz por la matriz de permutación P y la multiplicación posterior por P ^ -1 = P ^ T, pero esta no es una solución computacionalmente razonable.
En este momento estoy intercambiando manualmente filas y columnas, pero hubiera esperado que numpy tuviera una buena función f (M, v) donde M tiene n filas y columnas, y v tiene n entradas, de modo que f (M, v) se actualiza M de acuerdo con el índice de permutación v. Tal vez simplemente no estoy buscando en Internet.
Algo así podría ser posible con la "indexación avanzada" de numpy, pero entiendo que tal solución no estaría en su lugar. También para algunas situaciones simples puede ser suficiente rastrear por separado una permutación de índice, pero esto no es conveniente en mi caso.
Agregado: a
veces, cuando las personas hablan de permutaciones, solo se refieren al muestreo de permutaciones aleatorias, por ejemplo, como parte de un procedimiento para obtener valores p en las estadísticas. O significan contar o enumerar todas las permutaciones posibles. No estoy hablando de estas cosas.
Agregado:
la matriz es lo suficientemente pequeña como para caber en la RAM del escritorio, pero lo suficientemente grande como para que no quiera copiarla sin pensar. En realidad, me gustaría usar matrices lo más grandes posible, pero no quiero lidiar con el inconveniente de no poder mantenerlas en la RAM, y hago operaciones de O (N ^ 3) LAPACK en la matriz que también limitar el tamaño práctico de la matriz. Actualmente copio matrices tan grandes innecesariamente, pero espero que esto pueda evitarse fácilmente para la permutación.
fuente
M[v]
para permutar las filas.Respuestas:
Según los documentos, no hay un método de permutación en el lugar en numpy, algo así como ndarray.sort .
Entonces, sus opciones son (suponiendo quenorte× N
M
sea una matriz y el vector de permutación)p
Espero que estos hacks subóptimos sean útiles.
fuente
Advertencia: El siguiente ejemplo funciona correctamente, pero el uso del conjunto completo de parámetros sugeridos al final de la publicación expone un error , o al menos una "característica no documentada" en la función numpy.take (). Vea los comentarios a continuación para más detalles. Informe de error archivado .
Puede hacerlo en el lugar con la función take () de numpy , pero requiere un poco de salto de aro.
Aquí hay un ejemplo de hacer una permutación aleatoria de las filas de una matriz de identidad:
Para hacerlo en el lugar, todo lo que necesita hacer es especificar el parámetro "out" para que sea el mismo que la matriz de entrada Y debe configurar mode = "clip" o mode = "wrap". Si no configura el modo, realizará una copia para restaurar el estado de la matriz en una excepción de Python (consulte aquí) .
En una nota final, take parece ser un método de matriz, así que en lugar de
podrías llamar
si eso es más a tu gusto. Entonces, en total, la llamada debe tener un aspecto similar al siguiente:
Para permutar tanto las filas como las columnas, creo que tienes que ejecutarlo dos veces, o sacar algunas travesuras feas con numpy.unravel_index que me duele la cabeza al pensar.
fuente
1.6.2
,test take, not overwriting: True
,test not-in-place take: True
,test in-place take: False
,rr [3, 7, 8, 1, 4, 5, 9, 0, 2, 6]
,arr [30 70 80 70 40 50 90 30 80 90]
,ref [30 70 80 10 40 50 90 0 20 60]
. Entonces,np.take
al menos para numpy 1.6.2 no es consciente de hacer una permutación en el lugar y arruina las cosas.Si tiene una matriz dispersa almacenada en
COO
formato, lo siguiente podría ser útilsuponiendo quem m
A
contiene laCOO
matriz, yperm
es un quenumpy.array
contiene la permutación. Esto solo tendrá sobrecarga de memoria, donde es el número de elementos distintos de cero de la matriz.mfuente
C00
matriz dispersa en primer lugar?int
sy 1float
en representación dispersa por elemento como un solofloat
en la representación densa). Pero la sobrecarga de memoria de este método será en un caso denso, por lo que probablemente se podría seguir mejor con s normal .numpy.ndarray
No tengo suficiente reputación para comentar, pero creo que la siguiente pregunta SO podría ser útil: /programming/4370745/view-onto-a-numpy-array
Los puntos básicos son que se puede utilizar rebanar básica y que va a crear una visión de a la matriz sin necesidad de copiar, pero si lo hace avanzada rebanar / indexación entonces se van a crear una copia.
fuente
Qué pasa
my_array [:, [0, 1]] = my_array [:, [1, 0]]
fuente