Dalam numpy
, beberapa operasi kembali dalam bentuk (R, 1)
tetapi beberapa kembali (R,)
. Ini akan membuat perkalian matriks lebih membosankan karena reshape
diperlukan eksplisit . Sebagai contoh, diberi matriks M
, jika kita ingin melakukan di numpy.dot(M[:,0], numpy.ones((1, R)))
mana R
jumlah baris (tentu saja, masalah yang sama juga terjadi pada kolom-bijaksana). Kami akan mendapatkan matrices are not aligned
kesalahan karena M[:,0]
dalam bentuk (R,)
tetapi numpy.ones((1, R))
dalam bentuk (1, R)
.
Jadi pertanyaan saya adalah:
Apa perbedaan antara bentuk
(R, 1)
dan(R,)
. Saya tahu daftar nomor dan daftar di mana semua daftar hanya berisi angka. Hanya ingin tahu mengapa tidak mendesainnumpy
sehingga lebih menyukai bentuk(R, 1)
daripada(R,)
untuk perkalian matriks yang lebih mudah.Adakah cara yang lebih baik untuk contoh di atas? Tanpa secara eksplisit membentuk kembali seperti ini:
numpy.dot(M[:,0].reshape(R, 1), numpy.ones((1, R)))
Jawaban:
1. Arti bentuk dalam NumPy
Anda menulis, "Saya tahu ini daftar angka dan daftar daftar di mana semua daftar hanya berisi angka" tetapi itu sedikit cara yang tidak membantu untuk memikirkannya.
Cara terbaik untuk berpikir tentang array NumPy adalah bahwa mereka terdiri dari dua bagian, buffer data yang hanya merupakan blok elemen mentah, dan pandangan yang menjelaskan cara menafsirkan buffer data.
Misalnya, jika kita membuat array 12 bilangan bulat:
Kemudian
a
terdiri dari buffer data, disusun seperti ini:dan tampilan yang menjelaskan cara menafsirkan data:
Di sini bentuknya
(12,)
berarti array diindeks oleh indeks tunggal yang berjalan dari 0 hingga 11. Secara konseptual, jika kita memberi label pada indeks tunggal inii
, array tersebuta
terlihat seperti ini:Jika kami membentuk kembali sebuah array, ini tidak mengubah buffer data. Alih-alih, itu menciptakan tampilan baru yang menjelaskan cara berbeda untuk menginterpretasikan data. Jadi setelah:
array
b
memiliki buffer data yang sama dengana
, tetapi sekarang diindeks oleh dua indeks yang berjalan dari 0 ke 2 dan 0 hingga 3 masing-masing. Jika kami memberi label pada dua indeksi
danj
, arrayb
terlihat seperti ini:yang berarti:
Anda dapat melihat bahwa indeks kedua berubah dengan cepat dan indeks pertama berubah dengan lambat. Jika Anda memilih ini sebagai sebaliknya, Anda dapat menentukan
order
parameter:yang menghasilkan array yang diindeks seperti ini:
yang berarti:
Seharusnya sekarang menjadi jelas apa artinya bagi array untuk memiliki bentuk dengan satu atau lebih dimensi ukuran 1. Setelah:
array
d
diindeks oleh dua indeks, yang pertama berjalan dari 0 hingga 11, dan indeks kedua selalu 0:sehingga:
Dimensi panjang 1 adalah "bebas" (dalam arti tertentu), jadi tidak ada yang menghentikan Anda untuk pergi ke kota:
memberikan array yang diindeks seperti ini:
sehingga:
Lihat dokumentasi internal NumPy untuk detail lebih lanjut tentang bagaimana array diterapkan.
2. Apa yang harus dilakukan?
Karena
numpy.reshape
hanya menciptakan tampilan baru, Anda tidak perlu takut menggunakannya kapan pun diperlukan. Ini alat yang tepat untuk digunakan ketika Anda ingin mengindeks array dengan cara yang berbeda.Namun, dalam perhitungan yang panjang biasanya memungkinkan untuk mengatur untuk membangun array dengan bentuk "benar", dan dengan demikian meminimalkan jumlah pembentukan kembali dan transpos. Tetapi tanpa melihat konteks aktual yang mengarah pada kebutuhan untuk membentuk kembali, sulit untuk mengatakan apa yang harus diubah.
Contoh dalam pertanyaan Anda adalah:
tetapi ini tidak realistis. Pertama, ungkapan ini:
menghitung hasilnya lebih sederhana. Kedua, apakah benar-benar ada sesuatu yang istimewa tentang kolom 0? Mungkin yang sebenarnya Anda butuhkan adalah:
sumber
newaxis
jika Anda memerlukan sumbu lain, misalnyaa[:, j, np.newaxis]
adalahj
kolom tha
, dana[np.newaxis, i]
adalahi
baris th.(R, )
kasus ini, bentuknyandarray
adalah tuple dengan elemen tunggal, sehingga dicetak oleh Python dengan tanda koma. Tanpa koma ekstra, itu akan menjadi ambigu dengan ekspresi dalam tanda kurung . Andarray
dengan dimensi tunggal dapat berupa sebagai vektor panjang kolomR
. Dalam(R, 1)
kasus, tupel memiliki dua elemen, sehingga dapat dianggap sebagai vektor baris (atau matriks dengan 1 baris panjangR
.Perbedaan antara
(R,)
dan(1,R)
secara harfiah jumlah indeks yang perlu Anda gunakan.ones((1,R))
adalah array 2-D yang kebetulan hanya memiliki satu baris.ones(R)
adalah vektor. Umumnya jika tidak masuk akal untuk variabel memiliki lebih dari satu baris / kolom, Anda harus menggunakan vektor, bukan matriks dengan dimensi tunggal.Untuk kasus spesifik Anda, ada beberapa opsi:
1) Buat argumen kedua sebagai vektor. Berikut ini berfungsi dengan baik:
2) Jika Anda ingin operasi matlab seperti matriks, gunakan kelas
matrix
bukanndarray
. Semua matrik dipaksa menjadi array 2-D, dan operator*
melakukan perkalian matriks alih-alih elemen (sehingga Anda tidak perlu titik). Dalam pengalaman saya, ini lebih banyak masalah daripada nilainya, tetapi mungkin lebih baik jika Anda terbiasa dengan matlab.sumber
matrix
kelas. Apa masalah untukmatrix
kelas BTW?matrix
adalah itu hanya 2D, dan juga karena itu membebani operator '*', fungsi yang ditulis untukndarray
mungkin gagal jika digunakan pada amatrix
.Bentuknya adalah tuple. Jika hanya ada 1 dimensi bentuknya akan menjadi satu angka dan kosong setelah koma. Untuk 2+ dimensi, akan ada angka setelah semua koma.
sumber
Untuk kelas array dasarnya, array 2d tidak lebih spesial daripada 1d atau 3d. Ada beberapa operasi yang mempertahankan dimensi, beberapa yang menguranginya, lainnya menggabungkan atau bahkan memperluasnya.
Ekspresi lain yang memberikan array yang sama
MATLAB dimulai dengan hanya array 2D. Versi yang lebih baru memungkinkan lebih banyak dimensi, tetapi mempertahankan batas bawah 2. Tetapi Anda masih harus memperhatikan perbedaan antara matriks baris dan satu kolom, satu dengan bentuk
(1,3)
v(3,1)
. Seberapa sering Anda menulis[1,2,3].'
? Saya akan menulisrow vector
dancolumn vector
, tetapi dengan kendala 2d itu, tidak ada vektor di MATLAB - setidaknya tidak dalam pengertian matematika vektor sebagai 1d.Sudahkah Anda melihat
np.atleast_2d
(juga versi _1d dan _3d)?sumber
1) Alasan untuk tidak memilih bentuk
(R, 1)
over(R,)
adalah karena hal itu tidak perlu mempersulit. Selain itu, mengapa lebih disukai memiliki bentuk(R, 1)
secara default untuk vektor panjang-R daripada(1, R)
? Lebih baik untuk tetap sederhana dan eksplisit ketika Anda membutuhkan dimensi tambahan.2) Sebagai contoh, Anda menghitung produk luar sehingga Anda dapat melakukan ini tanpa
reshape
panggilan dengan menggunakannp.outer
:sumber
M[:,0]
pada dasarnya mendapatkan semua baris dengan elemen pertama, jadi lebih masuk akal untuk memiliki(R, 1)
daripada(1, R)
. 2) Ini tidak selalu dapat diganti dengannp.outer
, misalnya, titik untuk matriks dalam bentuk (1, R) lalu (R, 1).matrix
objek. 2) Sebenarnya,np.outer
bekerja terlepas dari apakah bentuk yang(1, R)
,(R, 1)
, atau kombinasi dari keduanya.Sudah banyak jawaban bagus di sini. Tetapi bagi saya itu sulit untuk menemukan beberapa contoh, di mana bentuk atau array dapat merusak semua program.
Jadi ini dia:
Ini akan gagal dengan kesalahan:
tetapi jika kita menambahkan
reshape
kea
:ini bekerja dengan benar!
sumber