Tương đương với repmat của MATLAB trong NumPy là gì


103

Tôi muốn thực hiện tương đương với mã MATLAB sau sử dụng NumPy: repmat([1; 1], [1 1 1]). Làm thế nào tôi sẽ thực hiện điều này?

Câu trả lời:


103

Đây là liên kết NumPy (chính thức) tốt hơn nhiều dành cho Người dùng Matlab - Tôi e rằng liên kết Mathesaurus đã khá lỗi thời.

Tương đương với numpy repmat(a, m, n)tile(a, (m, n)).

Điều này hoạt động với nhiều thứ nguyên và cho kết quả tương tự như matlab. (Numpy đưa ra mảng đầu ra 3d như bạn mong đợi - matlab vì lý do nào đó cho đầu ra 2d - nhưng nội dung thì giống nhau).

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]]])

2
khi tôi thử kích thước (repmat ([1; 1], [1,1,2])) nó nhận được ans = 2 1 2 [trong matlab] nhưng trong python np.tile (a, [1,1,2]) .shape nó nhận được (1, 2, 2), tôi muốn kết quả Cung cấp cho numpy như giống như matlab
vernomcrp

2
np.tile (a [:, np.newaxis], [1,1,2]) - nó cho kết quả tương tự. Vấn đề là ô xếp tăng cường akích thước của đối số ô bằng cách thêm các trục mới nếu cần. Matlab dường như hoạt động theo cách khác. Tương tự, với lát gạch 4d, bạn sẽ cần newaxis hai lần ... vì vậy np.tile(a[:,newaxis,newaxis],[1,2,3,4]) = size(repmat(a,[1 2 3 4]))theo yêu cầu ...
robince vào

17

Lưu ý rằng một số lý do bạn cần sử dụng repmat của MATLAB được giải quyết bởi cơ chế phát sóng của NumPy , cho phép bạn thực hiện nhiều dạng toán khác nhau với các mảng có hình dạng tương tự. Vì vậy, nếu bạn có, giả sử, một mảng 1600x1400x3 đại diện cho một hình ảnh 3 màu, bạn có thể (theo từng phần tử) nhân nó [1.0 0.25 0.25]với để giảm số lượng màu xanh lá cây và xanh lam ở mỗi pixel. Xem liên kết trên để biết thêm thông tin.


2
Không phải Matlab cũng có thể thực hiện việc phát sóng này, nếu bạn sử dụng bsxfun.
gerrit


8

Đây là cách tôi hiểu được nó sau một chút băn khoăn. Rất vui khi được sửa chữa và hy vọng điều này sẽ giúp ích.

Giả sử bạn có ma trận M gồm 2x3 phần tử. Điều này có hai chiều, rõ ràng.


Tôi không thể thấy sự khác biệt giữa Matlab và Python khi yêu cầu thao tác ma trận đầu vào dọc theo các kích thước mà ma trận đã có. Do đó, hai lệnh

repmat(M,m,n) % matlab

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

thực sự tương đương với một ma trận hạng 2 (hai chiều).


Các vấn đề trở nên phản trực quan khi bạn yêu cầu lặp lại / lát gạch trên nhiều kích thước hơn ma trận đầu vào có. Trở lại với ma trận M hạng hai và hình dạng 2x3, đủ để xem điều gì xảy ra với kích thước / hình dạng của ma trận đầu ra. Giả sử trình tự cho thao tác bây giờ là 1,1,2.

Trong Matlab

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

    2   3   2

nó đã sao chép hai kích thước đầu tiên (hàng và cột) của ma trận đầu vào và đã lặp lại điều đó một lần vào một chiều thứ ba mới (tức là đã sao chép hai lần). Đúng với cách đặt tên repmatcho ma trận lặp.

Trong Python

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

nó đã áp dụng một thủ tục khác vì, theo tôi, chuỗi (1,1,2) được đọc khác với trong Matlab. Số lượng bản sao theo hướng cột, hàng và kích thước ngoài mặt phẳng đang được đọc từ phải sang trái. Đối tượng kết quả có hình dạng khác với Matlab. Người ta không còn có thể khẳng định rằng repmattilecác hướng dẫn tương đương.


Để tilehoạt động như thế nào repmat, trong Python, người ta phải đảm bảo rằng ma trận đầu vào có nhiều thứ nguyên như các phần tử trong chuỗi. Ví dụ, điều này được thực hiện bằng cách điều chỉnh trước một chút và tạo một đối tượng liên quan N

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

Sau đó, ở phía đầu vào, người ta có N.shape = (2,3,1)hơn là M.shape = (2,3)và ở phía đầu ra

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

đó là câu trả lời của size(repmat(M,1,1,2)). Tôi cho rằng điều này là do chúng tôi đã hướng dẫn Python thêm chiều thứ ba vào bên phải của (2,3) thay vì bên trái của nó, để Python làm việc ra chuỗi (1,1,2) như nó đã được dự định trong Matlab cách đọc nó.

Các phần tử trong [:,:,0]trong câu trả lời Python cho N sẽ chứa các giá trị tương tự như nguyên tố này (:,:,1)là câu trả lời cho Matlab M .


Cuối cùng, tôi dường như không thể tìm thấy một repmatsản phẩm tương đương khi một người sử dụng sản phẩm Kronecker

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

trừ khi tôi điều kiện trước M thành N như trên. Vì vậy, tôi sẽ cho rằng cách chung nhất để tiếp tục là sử dụng các cách của np.newaxis.


Trò chơi trở nên phức tạp hơn khi chúng ta xem xét một ma trận L có hạng 3 (ba chiều) và trường hợp đơn giản là không có thứ nguyên mới nào được thêm vào trong ma trận đầu ra. Hai hướng dẫn dường như tương đương này sẽ không tạo ra kết quả giống nhau

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

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

bởi vì các hướng hàng, cột, ngoài mặt phẳng là (p, q, r) trong Matlab và (q, r, p) trong Python, không hiển thị với mảng cấp 2. Ở đó, người ta phải cẩn thận và việc thu được kết quả giống nhau với hai ngôn ngữ sẽ đòi hỏi điều kiện trước nhiều hơn.


Tôi biết rằng lý luận này có thể không chung chung, nhưng tôi chỉ có thể giải thích nó cho đến nay. Hy vọng rằng điều này sẽ mời các nghiên cứu sinh khác đưa nó vào một bài kiểm tra khó hơn.


6

Biết cả hai tilerepeat.

x = numpy.arange(5)
print numpy.tile(x, 2)
print x.repeat(2)

1

numpy.matlib có hàm repmat với giao diện tương tự như hàm matlab

from numpy.matlib import repmat
repmat( np.array([[1],[1]]) , 1, 1)

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]])
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.