Eu quero modificar uma matriz de transição quadrada densa no local, alterando a ordem de várias de suas linhas e colunas, usando a biblioteca numpy do python. Matematicamente, isso corresponde à pré-multiplicação da matriz pela matriz de permutação P e à pós-multiplicação por P ^ -1 = P ^ T, mas essa não é uma solução computacionalmente razoável.
No momento, estou trocando manualmente linhas e colunas, mas eu esperava que o numpy tivesse uma boa função f (M, v), onde M tem n linhas e colunas ev tem n entradas, para que f (M, v) seja atualizado M de acordo com a permutação de índice v. Talvez eu esteja apenas falhando ao pesquisar na internet.
Algo assim pode ser possível com a "indexação avançada" da numpy, mas meu entendimento é que essa solução não estaria em vigor. Também para algumas situações simples, pode ser suficiente rastrear apenas uma permutação de índice separadamente, mas isso não é conveniente no meu caso.
Adicionado:
Às vezes, quando as pessoas falam sobre permutações, elas significam apenas a amostragem de permutações aleatórias, por exemplo, como parte de um procedimento para obter valores de p em estatística. Ou eles significam contar ou enumerar todas as permutações possíveis. Eu não estou falando sobre essas coisas.
Adicionado:
a matriz é pequena o suficiente para caber na RAM da área de trabalho, mas grande o suficiente para que eu não queira copiá-la sem pensar. Na verdade, eu gostaria de usar matrizes tão grandes quanto possível, mas não quero lidar com o inconveniente de não poder mantê-las na RAM e faço O (N ^ 3) operações LAPACK na matriz, o que também limitar o tamanho da matriz prática. Atualmente, copio matrizes desse tamanho desnecessariamente, mas espero que isso possa ser facilmente evitado por permutação.
fonte
M[v]
para permutar as linhas.Respostas:
De acordo com os documentos, não existe um método de permutação no local em numpy, algo como ndarray.sort .
Portanto, suas opções são (assumindo queN× N
M
seja uma matriz e o vetor de permutação)p
Espero que esses hacks abaixo do ideal sejam úteis.
fonte
Aviso: O exemplo abaixo funciona corretamente, mas o uso do conjunto completo de parâmetros sugeridos no final da publicação expõe um bug ou pelo menos um "recurso não documentado" na função numpy.take (). Veja os comentários abaixo para obter detalhes. Relatório de bug arquivado .
Você pode fazer isso no local com a função take () de numpy , mas isso requer um pouco de pulos de argola.
Aqui está um exemplo de como fazer uma permutação aleatória das linhas de uma matriz de identidade:
Para fazer isso no local, tudo o que você precisa fazer é especificar o parâmetro "out" para ser o mesmo da matriz de entrada E você deve definir o mode = "clip" ou mode = "wrap". Se você não definir o modo, ele fará uma cópia para restaurar o estado do array em uma exceção do Python (veja aqui) .
Em uma nota final, take parece ser um método de matriz, portanto, em vez de
você poderia ligar
se isso é mais do seu gosto. Portanto, no total, você chama deve ser algo como o seguinte:
Para permutar linhas e colunas, acho que você precisa executá-lo duas vezes ou puxar algumas travessuras feias com numpy.unravel_index que machuca minha cabeça.
fonte
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]
. Portanto,np.take
pelo menos para o numpy 1.6.2 não está ciente de fazer uma permutação no local e estraga tudo.Se você possui uma matriz esparsa armazenada em
COO
formato, o seguinte pode ser útilA
COO
perm
numpy.array
fonte
C00
matriz esparsa em primeiro lugar?int
float
float
numpy.ndarray
Não tenho reputação suficiente para comentar, mas acho que a seguinte pergunta SO pode ser útil: /programming/4370745/view-onto-a-numpy-array
Os pontos básicos são que você pode usar o corte básico e que irá criar uma visão para a matriz sem copiar, mas se você fizer avançado corte / indexação em seguida, ele irá criar uma cópia.
fonte
Sobre o quê
minha matriz [:, [0, 1]] = minha matriz [:, [1, 0]]
fonte