Saya ingin memodifikasi matriks transisi persegi yang padat di tempat dengan mengubah urutan beberapa baris dan kolomnya, menggunakan perpustakaan numpy python. Secara matematis ini berhubungan dengan pra-mengalikan matriks dengan matriks permutasi P dan mengalikannya dengan P ^ -1 = P ^ T, tetapi ini bukan solusi yang masuk akal secara komputasi.
Saat ini saya secara manual bertukar baris dan kolom, tetapi saya berharap numpy memiliki fungsi yang bagus f (M, v) di mana M memiliki n baris dan kolom, dan v memiliki n entri, sehingga f (M, v) memperbarui M menurut indeks permutasi v. Mungkin saya hanya gagal mencari di internet.
Sesuatu seperti ini mungkin terjadi dengan "pengindeksan maju" numpy, tetapi pemahaman saya adalah bahwa solusi seperti itu tidak akan ada di tempat. Juga untuk beberapa situasi sederhana mungkin cukup untuk hanya secara terpisah melacak permutasi indeks, tetapi ini tidak nyaman dalam kasus saya.
Ditambahkan:
Kadang-kadang ketika orang berbicara tentang permutasi, mereka hanya berarti pengambilan sampel permutasi acak, misalnya sebagai bagian dari prosedur untuk mendapatkan nilai-p dalam statistik. Atau mereka berarti menghitung atau menghitung semua permutasi yang mungkin. Saya tidak membicarakan hal-hal ini.
Ditambahkan:
Matriks ini cukup kecil untuk masuk ke RAM desktop tetapi cukup besar sehingga saya tidak ingin menyalinnya tanpa berpikir. Sebenarnya saya ingin menggunakan matriks sebesar mungkin, tetapi saya tidak ingin berurusan dengan ketidaknyamanan karena tidak dapat menahan mereka dalam RAM, dan saya melakukan operasi O (N ^ 3) LAPACK pada matriks yang juga akan membatasi ukuran matriks praktis. Saya saat ini menyalin matriks sebesar ini tidak perlu, tetapi saya berharap ini dapat dengan mudah dihindari untuk permutasi.
sumber
M[v]
untuk mengubah baris.Jawaban:
Menurut dokumen, tidak ada metode permutasi di tempat di numpy, seperti ndarray.sort .
Jadi pilihan Anda (dengan asumsi bahwaN× N
M
adalah matriks dan vektor permutasi)p
memori overheadN
Memori overhead N 2N2
Semoga peretasan suboptimal ini bermanfaat.
sumber
Peringatan: Contoh di bawah ini berfungsi dengan baik, tetapi menggunakan set lengkap parameter yang disarankan di akhir posting memperlihatkan bug , atau setidaknya "fitur tidak terdokumentasi" di fungsi numpy.take (). Lihat komentar di bawah untuk detailnya. Laporan bug diajukan .
Anda dapat melakukan ini di tempat dengan fungsi take () numpy , tetapi membutuhkan sedikit lompatan melingkar.
Berikut adalah contoh melakukan permutasi acak dari baris-baris matriks identitas:
Untuk melakukannya di tempat, yang perlu Anda lakukan adalah menentukan parameter "out" agar sama dengan array input DAN Anda harus mengatur mode = "clip" atau mode = "wrap". Jika Anda tidak mengatur mode itu akan membuat salinan untuk mengembalikan keadaan array pada pengecualian Python (lihat di sini) .
Pada catatan terakhir, take tampaknya merupakan metode array, jadi alih-alih
Anda bisa menelepon
jika itu lebih sesuai dengan selera Anda. Jadi total yang Anda panggil akan terlihat seperti berikut:
Untuk mengubah kedua baris dan kolom saya pikir Anda harus menjalankannya dua kali, atau menarik beberapa shenanigans jelek dengan numpy.unravel_index yang menyakitkan kepala saya untuk dipikirkan.
sumber
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]
. Jadinp.take
setidaknya untuk numpy 1.6.2 tidak sadar melakukan permutasi di tempat dan mengacaukan segalanya.Jika Anda memiliki matriks jarang disimpan dalam
COO
format, berikut ini mungkin bermanfaatA
COO
perm
numpy.array
sumber
C00
matriks jarang di tempat pertama?int
float
float
numpy.ndarray
Saya tidak memiliki reputasi yang cukup untuk berkomentar, tetapi saya pikir pertanyaan SO berikut ini mungkin bermanfaat: /programming/4370745/view-onto-a-numpy-array
Poin dasar adalah bahwa Anda dapat menggunakan irisan dasar dan yang akan membuat tampilan ke array tanpa menyalin, tetapi jika Anda melakukan irisan / pengindeksan lanjutan maka itu akan membuat salinan.
sumber
Bagaimana dengan
my_array [:, [0, 1]] = my_array [:, [1, 0]]
sumber