Saya ingin mengiris array NumPy nxn. Saya ingin mengekstraksi pemilihan acak baris dan kolom array itu (yaitu tanpa pola dalam jumlah baris / kolom), menjadikannya array, mxm baru. Untuk contoh ini, katakanlah arraynya 4x4 dan saya ingin mengekstrak array 2x2 darinya.
Inilah susunan kami:
from numpy import *
x = range(16)
x = reshape(x,(4,4))
print x
[[ 0 1 2 3]
[ 4 5 6 7]
[ 8 9 10 11]
[12 13 14 15]]
Baris dan kolom yang akan dihapus sama. Kasus termudah adalah ketika saya ingin mengekstrak submatrix 2x2 yang ada di awal atau di akhir, yaitu:
In [33]: x[0:2,0:2]
Out[33]:
array([[0, 1],
[4, 5]])
In [34]: x[2:,2:]
Out[34]:
array([[10, 11],
[14, 15]])
Tetapi bagaimana jika saya harus menghapus campuran baris / kolom? Bagaimana jika saya harus menghapus baris / baris pertama dan ketiga, sehingga mengekstraksi submatrix [[5,7],[13,15]]
? Mungkin ada komposisi baris / garis. Saya membaca di suatu tempat bahwa saya hanya perlu mengindeks array saya menggunakan array / daftar indeks untuk baris dan kolom, tetapi sepertinya itu tidak berfungsi:
In [35]: x[[1,3],[1,3]]
Out[35]: array([ 5, 15])
Saya menemukan satu cara, yaitu:
In [61]: x[[1,3]][:,[1,3]]
Out[61]:
array([[ 5, 7],
[13, 15]])
Masalah pertama dengan ini adalah bahwa itu hampir tidak dapat dibaca, meskipun saya bisa hidup dengan itu. Jika seseorang memiliki solusi yang lebih baik, saya pasti ingin mendengarnya.
Hal lain yang saya baca di forum bahwa pengindeksan array dengan array memaksa NumPy untuk membuat salinan array yang diinginkan, sehingga ketika memperlakukan dengan array besar ini bisa menjadi masalah. Mengapa begitu / bagaimana mekanisme ini bekerja?
x[[[1],[3]],[1,3]]
hanya membuat satu array baru, sementarax[[1,3],:][:,[1,3]]
menyalin dua kali, jadi gunakan yang pertama.Saya tidak berpikir itu
x[[1,3]][:,[1,3]]
sulit dibaca. Jika Anda ingin lebih jelas tentang niat Anda, Anda dapat melakukan:Saya bukan ahli dalam mengiris tetapi biasanya, jika Anda mencoba mengiris menjadi array dan nilainya kontinu, Anda mendapatkan kembali tampilan di mana nilai langkahnya diubah.
mis. Dalam input Anda 33 dan 34, meskipun Anda mendapatkan array 2x2, langkahnya adalah 4. Jadi, ketika Anda mengindeks baris berikutnya, pointer bergerak ke posisi yang benar dalam memori.
Jelas, mekanisme ini tidak membawa kasus array indeks. Oleh karena itu, numpy harus membuat salinannya. Bagaimanapun, banyak fungsi matrik matematika lainnya bergantung pada ukuran, langkah, dan alokasi memori kontinu.
sumber
Jika Anda ingin melewati setiap baris lain dan setiap kolom lainnya, maka Anda bisa melakukannya dengan mengiris dasar:
Ini mengembalikan tampilan, bukan salinan array Anda.
saat
z=x[(1,3),:][:,(1,3)]
menggunakan pengindeksan tingkat lanjut dan dengan demikian mengembalikan salinan:Catatan yang
x
tidak berubah:Jika Anda ingin memilih baris dan kolom sewenang-wenang, maka Anda tidak dapat menggunakan pengirisan dasar. Anda harus menggunakan pengindeksan lanjutan, menggunakan sesuatu seperti
x[rows,:][:,columns]
, di mana,rows
dancolumns
urutan. Ini tentu saja akan memberi Anda salinan, bukan tampilan, dari array asli Anda. Ini seperti yang diharapkan, karena array numpy menggunakan memori yang berdekatan (dengan langkah konstan), dan tidak akan ada cara untuk menghasilkan tampilan dengan baris dan kolom sewenang-wenang (karena itu akan membutuhkan langkah tidak konstan).sumber
Dengan numpy, Anda bisa memberikan irisan untuk setiap komponen indeks - jadi,
x[0:2,0:2]
contoh Anda di atas berfungsi.Jika Anda hanya ingin melompati kolom atau baris secara merata, Anda dapat memberikan irisan dengan tiga komponen (yaitu mulai, berhenti, langkah).
Sekali lagi, untuk contoh Anda di atas:
Yang pada dasarnya adalah: iris dalam dimensi pertama, dengan mulai dari indeks 1, berhenti ketika indeks sama atau lebih besar dari 4, dan tambahkan 2 ke indeks di setiap pass. Hal yang sama untuk dimensi kedua. Sekali lagi: ini hanya berfungsi untuk langkah konstan.
Sintaks Anda harus melakukan sesuatu yang sangat berbeda secara internal - apa yang
x[[1,3]][:,[1,3]]
sebenarnya dilakukan adalah membuat array baru termasuk hanya baris 1 dan 3 dari array asli (dilakukan denganx[[1,3]]
bagian), dan kemudian mengiris ulang itu - membuat array ketiga - termasuk hanya kolom 1 dan 3 dari array sebelumnya.sumber
Saya memiliki pertanyaan serupa di sini: Menulis dalam sub-ndarray dari ndarray dengan cara yang paling pythonian. Python 2 .
Mengikuti solusi dari posting sebelumnya untuk kasus Anda, solusinya terlihat seperti:
Menggunakan ix_:
Yang mana:
sumber
Saya tidak yakin seberapa efisien ini tetapi Anda dapat menggunakan range () untuk memotong di kedua sumbu
sumber