Apa yang setara dengan repmat MATLAB di NumPy

103

Saya ingin mengeksekusi setara dengan kode MATLAB berikut menggunakan NumPy: repmat([1; 1], [1 1 1]). Bagaimana saya mencapai ini?

vernomcrp.dll
sumber

Jawaban:

103

Berikut ini adalah tautan NumPy untuk Pengguna Matlab (resmi) yang jauh lebih baik - Saya khawatir tautan mathesaurus sudah ketinggalan zaman.

Padanan numpy repmat(a, m, n)adalah tile(a, (m, n)).

Ini bekerja dengan banyak dimensi dan memberikan hasil yang mirip dengan matlab. (Numpy memberikan larik keluaran 3d seperti yang Anda harapkan - matlab karena alasan tertentu memberikan keluaran 2d - tetapi isinya sama).

Matlab:

>> repmat([1;1],[1,1,1])

ans =
     1
     1

Python:

In [46]: a = np.array([[1],[1]])
In [47]: np.tile(a, [1,1,1])
Out[47]: 
array([[[1],
        [1]]])
robince
sumber
2
ketika saya mencoba ukuran (repmat ([1; 1], [1,1,2])) itu mendapatkan ans = 2 1 2 [di matlab] tetapi di python np.tile (a, [1,1,2]) .bentuk itu dapatkan (1, 2, 2), saya ingin numpy memberikan hasil yang sama seperti matlab
vernomcrp
2
np.tile (a [:, np.newaxis], [1,1,2]) - memberikan hal yang sama. Masalahnya adalah petak mempromosikan adimensi argumen petak dengan menyiapkan sumbu baru jika diperlukan. Matlab tampaknya bekerja sebaliknya. Demikian pula, dengan pemasangan ubin 4d Anda akan membutuhkan sumbu baru dua kali ... jadi np.tile(a[:,newaxis,newaxis],[1,2,3,4]) = size(repmat(a,[1 2 3 4]))sesuai kebutuhan ...
robince
17

Perhatikan bahwa beberapa alasan Anda perlu menggunakan repmat MATLAB ditangani oleh mekanisme penyiaran NumPy , yang memungkinkan Anda melakukan berbagai jenis matematika dengan larik berbentuk serupa. Jadi, jika Anda memiliki, katakanlah, larik 1600x1400x3 yang mewakili gambar 3 warna, Anda dapat (berdasarkan elemen) mengalikannya dengan [1.0 0.25 0.25]untuk mengurangi jumlah hijau dan biru di setiap piksel. Lihat tautan di atas untuk informasi lebih lanjut.

kwatford.dll
sumber
2
Bukan berarti Matlab dapat melakukan penyiaran ini juga, jika Anda menggunakannya bsxfun.
gerrit
8

Beginilah cara saya memahaminya dari sedikit mengotak-atik. Senang bisa dikoreksi dan semoga ini membantu.

Katakanlah Anda memiliki matriks M dari elemen 2x3. Ini jelas memiliki dua dimensi.


Saya tidak bisa melihat perbedaan antara Matlab dan Python saat meminta untuk memanipulasi matriks masukan sepanjang dimensi yang sudah dimiliki matriks. Demikianlah kedua perintah tersebut

repmat(M,m,n) % matlab

np.tile(M,(m,n)) # python

benar-benar setara untuk matriks peringkat 2 (dua dimensi).


Masalahnya menjadi kontra-intuitif ketika Anda meminta pengulangan / ubin pada lebih banyak dimensi daripada yang dimiliki matriks input. Kembali ke matriks M dari peringkat dua dan bentuk 2x3, sudah cukup untuk melihat apa yang terjadi pada ukuran / bentuk matriks keluaran. Katakanlah urutan manipulasi sekarang 1,1,2.

Di Matlab

> size(repmat(M,1,1,2))
ans =

    2   3   2

itu telah menyalin dua dimensi pertama (baris dan kolom) dari matriks masukan dan telah mengulanginya sekali ke dimensi ketiga yang baru (disalin dua kali, yaitu). Sesuai dengan penamaan repmatuntuk matriks berulang.

Dengan Python

>>> np.tile(M,(1,1,2)).shape
(1, 2, 6)

itu telah menerapkan prosedur yang berbeda karena, saya kira, urutan (1,1,2) dibaca berbeda dari pada di Matlab. Jumlah salinan dalam arah kolom, baris, dan dimensi di luar bidang sedang dibaca dari kanan ke kiri. Objek yang dihasilkan memiliki bentuk yang berbeda dengan Matlab. Seseorang tidak dapat lagi menegaskan itu repmatdan tilemerupakan instruksi yang setara.


Untuk tileberperilaku seperti repmat, dalam Python seseorang harus memastikan bahwa matriks masukan memiliki dimensi sebanyak elemen dalam urutannya. Ini dilakukan, misalnya, dengan sedikit prakondisi dan membuat objek terkait N

N = M[:,:,np.newaxis]

Kemudian, di sisi masukan seseorang memiliki N.shape = (2,3,1)daripada M.shape = (2,3)dan di sisi keluaran

>>> np.tile(N,(1,1,2)).shape
(2, 3, 2)

yang merupakan jawaban dari size(repmat(M,1,1,2)). Saya kira ini karena kami telah memandu Python untuk menambahkan dimensi ketiga ke kanan (2,3) daripada ke kiri, sehingga Python mengerjakan urutan (1,1,2) seperti yang dimaksudkan di Matlab cara membacanya.

Unsur di [:,:,0]dalam jawaban Python untuk N akan berisi nilai yang sama seperti elemen (:,:,1)jawaban Matlab untuk M .


Akhirnya, saya tidak bisa menemukan padanan repmatketika seseorang menggunakan produk Kronecker dari

>>> np.kron(np.ones((1,1,2)),M).shape
(1, 2, 6)

kecuali saya kemudian memprakondisikan M menjadi N seperti di atas. Jadi saya berpendapat bahwa cara paling umum untuk melanjutkan adalah dengan menggunakan cara np.newaxis.


Permainan menjadi lebih rumit ketika kita mempertimbangkan matriks L dari peringkat 3 (tiga dimensi) dan kasus sederhana tidak ada dimensi baru yang ditambahkan dalam matriks keluaran. Kedua instruksi yang tampaknya setara ini tidak akan menghasilkan hasil yang sama

repmat(L,p,q,r) % matlab

np.tile(L,(p,q,r)) # python

karena baris, kolom, arah out-of-plane adalah (p, q, r) di Matlab dan (q, r, p) di Python, yang tidak terlihat dengan array rank-2. Di sana, seseorang harus berhati-hati dan mendapatkan hasil yang sama dengan dua bahasa akan membutuhkan lebih banyak pengkondisian awal.


Saya sadar bahwa alasan ini mungkin tidak umum, tetapi saya hanya bisa menyelesaikannya sejauh ini. Semoga ini mengundang rekan-rekan lainnya untuk mengujinya lebih keras.

XavierStuvw
sumber
6

Tahu keduanya tiledan repeat.

x = numpy.arange(5)
print numpy.tile(x, 2)
print x.repeat(2)
Steve Tjoa
sumber
1

numpy.matlib memiliki repmat fungsi dengan antarmuka yang mirip dengan fungsi matlab

from numpy.matlib import repmat
repmat( np.array([[1],[1]]) , 1, 1)
e-malito.dll
sumber
0
>>> import numpy as np

>>> np.repeat(['a','b'], [2,5])

array(['a', 'a', 'b', 'b', 'b', 'b', 'b'], dtype='<U1')

>>> np.repeat([1,2], [2,5])

array([1, 1, 2, 2, 2, 2, 2])

>>> np.repeat(np.array([1,2]), [3]).reshape(2,3)

array([[1, 1, 1],
       [2, 2, 2]])

>>> np.repeat(np.array([1,2]), [2,4]).reshape(3,2)

array([[1, 1],
       [2, 2],
       [2, 2]])

>>> np.repeat(np.matrix('1 2; 3 4'), [2]).reshape(4,2)

matrix([[1, 1],
        [2, 2],
        [3, 3],
        [4, 4]])
Shivid
sumber