2016-05-26 37 views
5

Tôi có một mảng/thiết lập với số nguyên dương độc đáo, tức làNumPy tìm chỉ số phần tử trong mảng khác

>>> unique = np.unique(np.random.choice(100, 4, replace=False)) 

Và một mảng chứa nhiều phần tử được lấy mẫu từ mảng trước đây, chẳng hạn như

>>> A = np.random.choice(unique, 100) 

Tôi muốn ánh xạ các giá trị của mảng A đến vị trí mà các giá trị đó xuất hiện trong unique.

Cho đến nay các giải pháp tốt nhất mà tôi tìm thấy là thông qua một mảng bản đồ:

>>> table = np.zeros(unique.max()+1, unique.dtype) 
>>> table[unique] = np.arange(unique.size) 

Các chuyển nhượng trên để mỗi phần tử chỉ số trên mảng, và do đó, có thể được sử dụng sau này để lập bản đồ A qua indexing tiên tiến:

>>> table[A] 
array([2, 2, 3, 3, 3, 3, 1, 1, 1, 0, 2, 0, 1, 0, 2, 1, 0, 0, 2, 3, 0, 0, 0, 
     0, 3, 3, 2, 1, 0, 0, 0, 2, 1, 0, 3, 0, 1, 3, 0, 1, 2, 3, 3, 3, 3, 1, 
     3, 0, 1, 2, 0, 0, 2, 3, 1, 0, 3, 2, 3, 3, 3, 1, 1, 2, 0, 0, 2, 0, 2, 
     3, 1, 1, 3, 3, 2, 1, 2, 0, 2, 1, 0, 1, 2, 0, 2, 0, 1, 3, 0, 2, 0, 1, 
     3, 2, 2, 1, 3, 0, 3, 3], dtype=int32) 

Điều này đã mang lại cho tôi giải pháp phù hợp. Tuy nhiên, nếu các số duy nhất trong unique rất thưa thớt và lớn, cách tiếp cận này ngụ ý tạo một mảng table rất lớn chỉ để lưu trữ một vài số để ánh xạ sau này.

Có giải pháp nào tốt hơn?

LƯU Ý: cả hai Aunique là các mảng mẫu, không mảng thực. Vì vậy, vấn đề không phải là làm thế nào để tạo ra chỉ số vị trí, nó chỉ là làm thế nào để lập bản đồ một cách hiệu quả các yếu tố của A để chỉ số trong unique, các giả về những gì tôi muốn tăng tốc trong NumPy được như sau,

B = np.zeros_like(A) 
for i in range(A.size): 
    B[i] = unique.index(A[i]) 

(giả sử unique là một danh sách ở trên mã giả).

Trả lời

4

Cách tiếp cận bảng mô tả trong câu hỏi của bạn là lựa chọn tốt nhất khi unique nếu khá dày đặc, nhưng unique.searchsorted(A) nên tạo ra kết quả tương tự và không đòi hỏi unique để dày đặc. searchsorted là tuyệt vời với ints, nếu bất cứ ai đang cố gắng để làm điều này loại điều với phao có giới hạn chính xác, xem xét một cái gì đó như this.

+0

Và 'sorter' có thể được sử dụng với nó, nếu' unique' chưa được sắp xếp. – Divakar

1

Bạn có thể sử dụng tiêu chuẩn python dict với np.vectorize

inds = {e:i for i, e in enumerate(unique)} 
B = np.vectorize(inds.get)(A) 
+0

Cách tiếp cận thú vị, tôi sẽ phải kiểm tra hiệu suất của 'np.vectorize' đối với các ma trận lớn. –

+0

np.vectorize vòng trên cấp độ python, vì vậy không cần phải thực hiện kiểm tra ... chỉ cú pháp của nó đường –

2

Các numpy_indexed gói (từ chối trách nhiệm: Tôi là tác giả của nó) có chứa một tương đương vectorized của list.index, mà không yêu cầu bộ nhớ tương ứng với các yếu tố tối đa, nhưng chỉ có tỷ lệ với đầu vào chính nó:

import numpy_indexed as npi 
npi.indices(unique, A) 

Lưu ý rằng nó cũng hoạt động cho các loại dtypes và kích thước tùy ý. Ngoài ra, mảng được truy vấn không cần phải là duy nhất; chỉ số đầu tiên gặp phải sẽ được trả lại, giống như danh sách.

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