2011-10-19 30 views

Trả lời

19

Tài liệu tham chiếu của page on indexing NumPy chứa các câu trả lời, nhưng đòi hỏi một chút đọc cẩn thận.

Câu trả lời ở đây là việc lập chỉ mục với các phép toán tương đương với việc lập chỉ mục với các mảng số nguyên thu được bằng cách lần đầu tiên chuyển các mảng boolean bằng np.nonzero. Vì vậy, với mảng boolean m1, m2

a[m1, m2] == a[m1.nonzero(), m2.nonzero()] 

đó (khi nó thành công, tức là, m1.nonzero().shape == m2.nonzero().shape) tương đương với:

[a[i, i] for i in range(a.shape[0]) if m1[i] and m2[i]] 

Tôi không chắc chắn lý do tại sao nó được thiết kế để làm việc như thế này - - thông thường, đây là không phải những gì bạn muốn.

Để có được kết quả trực quan hơn, bạn thay vì có thể làm

a[np.ix_(m1, m2)] 

mà tạo ra một kết quả tương đương với

[[a[i,j] for j in range(a.shape[1]) if m2[j]] for i in range(a.shape[0]) if m1[i]] 
+1

Nó thực sự không có ý nghĩa. Tôi sẽ hỏi trong maillist tại sao nó là theo cách này. – tillsten

+1

[scipy.org/Cookbook/Indexing] (http://scipy.org/Cookbook/Indexing) p. 14 về chỉ số Boolean đa chiều cho biết "nhìn vào các công cụ mảng bị che khuất của numpy ... Cách tiếp cận rõ ràng không đưa ra câu trả lời đúng." (Tài liệu đó được viết tốt, cần cập nhật.) – denis

+0

@denis, vào khoảng năm 2013 tài liệu đó giải thích rõ ràng. Tuy nhiên, nếu bạn google lập chỉ mục logic gumpy, tài liệu đi lên là http://docs.scipy.org/doc/numpy/reference/arrays.indexing.html và nó không được giải thích gần như là tốt. – John

4

Một thay thế cho np.ix_ là để chuyển đổi các mảng boolean để nguyên mảng (sử dụng np.nonzero()), sau đó sử dụng np.newaxis để tạo các mảng có hình dạng phù hợp để tận dụng phát sóng.

import numpy as np 

a=np.random.rand(10,20) 
x_range=np.arange(10) 
y_range=np.arange(20) 

a_tmp=a[x_range<5,:] 
b_correct=a_tmp[:,np.in1d(y_range,[3,4,8])] 

m1=(x_range<5).nonzero()[0] 
m2=np.in1d(y_range,[3,4,8]).nonzero() 
b=a[m1[:,np.newaxis], m2] 
assert np.allclose(b,b_correct) 

b2=a[np.ix_(x_range<5,np.in1d(y_range,[3,4,8]))] 
assert np.allclose(b2,b_correct) 

np.ix_ có xu hướng chậm hơn lập chỉ mục kép. giải pháp Các dài hình thức dường như là nhanh hơn một chút:

dài dạng:

In [83]: %timeit a[(x_range<5).nonzero()[0][:,np.newaxis], (np.in1d(y_range,[3,4,8])).nonzero()[0]] 
10000 loops, best of 3: 131 us per loop 

đôi indexing:

In [85]: %timeit a[x_range<5,:][:,np.in1d(y_range,[3,4,8])] 
10000 loops, best of 3: 144 us per loop 

sử dụng np.ix_:

In [84]: %timeit a[np.ix_(x_range<5,np.in1d(y_range,[3,4,8]))] 
10000 loops, best of 3: 160 us per loop 

Lưu ý: Bạn nên kiểm tra những thời gian này trên máy của mình vì các thứ hạng có thể thay đổi tùy thuộc vào phiên bản Python, phần mềm hay phần cứng của bạn.