2012-07-09 76 views
9

Trong cả MATLAB và Numpy, mảng có thể được lập chỉ mục theo mảng. Tuy nhiên, hành vi là khác nhau. Hãy để tôi giải thích điều này bằng một ví dụ.Lập chỉ mục mảng giống MATLAB với Numpy

MATLAB:

>> A = rand(5,5) 

A = 

    0.1622 0.6020 0.4505 0.8258 0.1067 
    0.7943 0.2630 0.0838 0.5383 0.9619 
    0.3112 0.6541 0.2290 0.9961 0.0046 
    0.5285 0.6892 0.9133 0.0782 0.7749 
    0.1656 0.7482 0.1524 0.4427 0.8173 

>> A([1,3,5],[1,3,5]) 

ans = 

    0.1622 0.4505 0.1067 
    0.3112 0.2290 0.0046 
    0.1656 0.1524 0.8173 

NumPy:

In [2]: A = arange(25).reshape((5,5)) 

In [3]: A 
Out[3]: 
array([[ 0, 1, 2, 3, 4], 
     [ 5, 6, 7, 8, 9], 
     [10, 11, 12, 13, 14], 
     [15, 16, 17, 18, 19], 
     [20, 21, 22, 23, 24]]) 

In [6]: A[[0,2,4], [0,2,4]] 
Out[6]: array([ 0, 12, 24]) 

Bằng chữ: MATLAB chọn hàng và cột, numpy "kéo khóa" hai mảng chỉ mục và sử dụng các bộ để trỏ đến mục.

Làm cách nào để có hành vi MATLAB với Numpy?

Trả lời

7

Bạn có thể làm điều này:

A[[0,2,4],:][:,[0,2,4]] 

mà sẽ cung cấp cho các kết quả MATLAB giống như bạn muốn.

Nó có giá trị là nhận thức được rằng, thay vì không nhất quán, nếu bạn sử dụng lát cho chỉ mục sau đó bạn sẽ có được kết quả MATLAB giống như không có bất kỳ hackery ví dụ:

>>> A[1:3,1:3] 
array([[ 6, 7], 
     [11,12]]) 

Trong NumPy, không giống như MATLAB, 1:3 không chỉ là một từ viết tắt cho [1,2] hoặc bất kỳ thứ gì thuộc loại này. (Tại thời điểm đó tôi cảm thấy bắt buộc phải đề cập đến một cái gì đó bạn chắc chắn biết rồi, cụ thể là Python của 1:3 là kinda như [1,2] trong khi MATLAB là kinda như [1,2,3]:. Điểm cuối bên tay phải được bao gồm trong MATLAB và loại trừ trong Python)

+3

Đây là thực sự khá hiệu quả. Nó yêu cầu tạo một mảng tạm thời trong bộ nhớ có thể khá lớn tùy thuộc vào kích thước của mảng mà bạn đang làm việc. Có một số cách hiệu quả hơn để thực hiện việc này, bao gồm cả việc sử dụng hàm trợ giúp ix_. –

+2

Yup, tất cả đều chính xác. Mặt khác, thứ được xây dựng bởi 'ix_' cũng khá lớn, mặc dù tạm thời. Tôi đã thực hiện một số thử nghiệm thời gian cho một mảng 5x5 như trong câu hỏi ban đầu, với các kết quả sau. '[,:] [:,]' nhanh hơn khoảng 25% so với '[ix _()]', nhưng nếu bạn đang sử dụng cùng các chỉ mục mỗi lần thì hãy xây dựng một mảng lập chỉ mục * một lần * với 'ix_' và sử dụng lại nó là khoảng 10 lần nhanh hơn - mặc dù tất nhiên bạn sau đó phải trả một chi phí trong việc sử dụng bộ nhớ. –

+2

np.ix_, trong hầu hết các trường hợp, chỉ sử dụng một lượng bộ nhớ tầm thường vì nó trả về các quan điểm của đối số của nó. Ngoài ra np.ix_ là một hoạt động thời gian không đổi trong khi A [I1,:] [:, I2] là ~ n^2 trong cả thời gian và mức sử dụng bộ nhớ. Nhưng nếu bạn thực sự cần tăng 25% hiệu suất trên mảng 5x5 của mình, bạn phải làm những gì bạn phải làm. –

14

Bạn có thể sử dụng chức năng helper numpy.ix_ để có được những hành vi Matlab:

from numpy import ix_ 
A[ ix_([0,2,4], [0,2,4]) ] 
1

cách hiệu quả để làm điều này với numPy là để định hình lại mảng chỉ số của bạn để phù hợp với các trục họ đang lập chỉ mục tức là

In [103]: a=numpy.arange(100).reshape(10,10) 

In [104]: a 
Out[104]: 
array([[ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9], 
    [10, 11, 12, 13, 14, 15, 16, 17, 18, 19], 
    [20, 21, 22, 23, 24, 25, 26, 27, 28, 29], 
    [30, 31, 32, 33, 34, 35, 36, 37, 38, 39], 
    [40, 41, 42, 43, 44, 45, 46, 47, 48, 49], 
    [50, 51, 52, 53, 54, 55, 56, 57, 58, 59], 
    [60, 61, 62, 63, 64, 65, 66, 67, 68, 69], 
    [70, 71, 72, 73, 74, 75, 76, 77, 78, 79], 
    [80, 81, 82, 83, 84, 85, 86, 87, 88, 89], 
    [90, 91, 92, 93, 94, 95, 96, 97, 98, 99]]) 

In [105]: x=numpy.array([3,6,9]) 

In [106]: y=numpy.array([2,7,8]) 

In [107]: a[x[:,numpy.newaxis],y[numpy.newaxis,:]] 
Out[107]: 
array([[32, 37, 38], 
     [62, 67, 68], 
     [92, 97, 98]]) 

quy tắc của phát thanh truyền hình NumPy của là bạn của bạn (và tốt hơn rất nhiều so với matlab) ...

HTH

Các vấn đề liên quan