2017-12-15 89 views
7

tôi có:NumPy mảng lập chỉ mục với các danh sách và mảng

>>> a 
array([[1, 2], 
     [3, 4]]) 

>>> type(l), l # list of scalers 
(<type 'list'>, [0, 1]) 

>>> type(i), i # a numpy array 
(<type 'numpy.ndarray'>, array([0, 1])) 

>>> type(j), j # list of numpy arrays 
(<type 'list'>, [array([0, 1]), array([0, 1])]) 

Khi tôi làm

>>> a[l] # Case 1, l is a list of scalers 

tôi nhận được

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

có nghĩa lập chỉ mục chỉ xảy ra trên trục 0.

Nhưng khi tôi làm

>>> a[j] # Case 2, j is a list of numpy arrays 

tôi nhận được

array([1, 4]) 

có nghĩa lập chỉ mục đã xảy ra dọc theo trục 0 và trục 1.

Q1: Khi được sử dụng để lập chỉ mục, tại sao có sự khác biệt trong việc xử lý danh sách các scalers và danh sách các mảng có nhiều mảng? (Trường hợp 1 so với Trường hợp 2). Trong trường hợp 2, tôi đã hy vọng để xem chỉ mục chỉ xảy ra dọc theo trục 0 và nhận được

array([[[1,2], 
      [3,4]], 

     [[1,2], 
     [3,4]]]) 

Bây giờ, khi sử dụng mảng NumPy mảng thay vì

>>> j1 = np.array(j) # numpy array of arrays 

Kết quả dưới đây chỉ ra rằng indexing xảy ra chỉ cùng trục 0 (như mong đợi)

>>> a[j1] Case 3, j1 is a numpy array of numpy arrays 
array([[[1, 2], 
     [3, 4]], 

     [[1, 2], 
     [3, 4]]]) 

Q2: Khi sử dụng cho lập chỉ mục, tại sao lại có sự khác biệt trong điều trị các danh sách các mảng numPy và n mảng umpy của mảng numpy? (Trường hợp 2 so với Trường hợp 3)

+0

Đối với Q1, không phải là số không tương tự không sử dụng Numpy để sử dụng 'k = [[0,1], [0,1]]; a [k] '? Trong trường hợp đó, bạn sẽ thấy cùng một hành vi giữa một danh sách các danh sách và một danh sách các mảng Numpy. –

+0

Một cách khác để xem xét nó là '[a [jj] cho jj trong j]' cung cấp cho bạn những gì bạn mong đợi trong Q1. Nhập một danh sách các danh sách, cho dù một mảng Numpy hay không, về cơ bản là trả về một tập hợp các chỉ mục tại một thời điểm. –

Trả lời

1

Case1, a[l] thực sự là a[(l,)] mở rộng thành a[(l, slice(None))]. Tức là, lập chỉ mục thứ nguyên đầu tiên với danh sách l và một lát tự động :. Các chỉ số được chuyển thành một bộ dữ liệu tới mảng __getitem__ và thêm () có thể được thêm vào mà không bị nhầm lẫn.

Case2, a[j] được coi là a[array([0, 1]), array([0, 1]] hoặc a[(array(([0, 1]), array([0, 1])]. Nói cách khác, như một bộ các đối tượng lập chỉ mục, một đối tượng trên mỗi thứ nguyên. Kết thúc trả lại a[0,0]a[1,1].

Trường hợp3, a[j1]a[(j1, slice(None))], chỉ áp dụng chỉ số j1 cho thứ nguyên đầu tiên.

Case2 hơi có chút bất thường. Trực giác của bạn là hợp lệ, nhưng vì lý do lịch sử, danh sách các mảng (hoặc danh sách các danh sách) được hiểu là một bộ các mảng.

Điều này đã được thảo luận trong các câu hỏi SO khác và tôi nghĩ rằng đó là tài liệu. Nhưng tôi không thể tìm thấy những tài liệu tham khảo đó.

Vì vậy, an toàn hơn để sử dụng một bộ các đối tượng lập chỉ mục hoặc một mảng. Lập chỉ mục với một danh sách có một sự mơ hồ tiềm ẩn.


numpy array indexing: list index and np.array index give different result

Câu hỏi này SO chạm vào cùng một vấn đề, mặc dù tuyên bố rõ ràng về những gì đang xảy ra được chôn cất trong một liên kết mã trong một bình luận bởi @ user2357112.

Một cách khác để buộc Case3 như lập chỉ mục, làm cho kích thước miếng thứ 2 rõ ràng, a[j,:]

In [166]: a[j] 
Out[166]: array([1, 4]) 
In [167]: a[j,:] 
Out[167]: 
array([[[1, 2], 
     [3, 4]], 

     [[1, 2], 
     [3, 4]]]) 

(tôi thường bao gồm các trailing : ngay cả khi nó không phải là cần thiết. Nó làm cho nó rõ ràng với tôi, và độc giả, chúng tôi đang làm việc với bao nhiêu chiều.)

0

A1: Cấu trúc của l không giống như j.

l chỉ là một chiều trong khi j là hai chiều. Nếu bạn thay đổi một trong số chúng:

# l = [0, 1]         # just one dimension! 
l = [[0, 1], [0, 1]]       # two dimensions 
j = [np.array([0,1]), np.array([0, 1])]  # two dimensions 

Chúng có cùng hành vi.

A2: Tương tự, cấu trúc của mảng trong Trường hợp 2 và Trường hợp 3 không giống nhau.

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