2013-04-11 55 views
18

Vấn đề này có vẻ dễ dàng nhưng tôi không thể có được một giải pháp đẹp mắt. Tôi có hai mảng numpy (A và B), và tôi muốn lấy các chỉ số A, trong đó các phần tử A nằm trong B và cũng có các chỉ số A, trong đó các phần tử không có trong B.Kiểm tra xem mỗi phần tử trong một mảng có nhiều mảng nằm trong một mảng khác

Vì vậy, nếu

A = np.array([1,2,3,4,5,6,7]) 
B = np.array([2,4,6]) 

Hiện nay tôi đang sử dụng

C = np.searchsorted(A,B) 

mà lợi dụng thực tế là A là theo thứ tự, và mang lại cho tôi [1, 3, 5], các chỉ số của các yếu tố có trong A. Điều này thật tuyệt, nhưng làm cách nào để nhận được D = [0,2,4,6], chỉ mục của các thành phần của A không nằm trong số B?

Trả lời

6
import numpy as np 

A = np.array([1,2,3,4,5,6,7]) 
B = np.array([2,4,6]) 
C = np.searchsorted(A, B) 

D = np.delete(np.arange(np.alen(A)), C) 

D 
#array([0, 2, 4, 6]) 
+0

Cảm ơn! Tôi cũng thích câu trả lời được cung cấp bởi alexhb bằng cách sử dụng np.setdiff1d. Tôi đã hy vọng rằng có một chức năng có thể đưa cho tôi các chỉ số trực tiếp, nhưng nó hoạt động tốt. – DanHickstein

+0

Có thể có, @Dan, nhưng tôi không thể nghĩ về nó. Nếu bạn không cần 'C', sử dụng giải pháp của mình, nhưng tôi sẽ nhanh gấp đôi nếu bạn đã có' C'. – askewchan

3
import numpy as np 

a = np.array([1, 2, 3, 4, 5, 6, 7]) 
b = np.array([2, 4, 6]) 
c = np.searchsorted(a, b) 
d = np.searchsorted(a, np.setdiff1d(a, b)) 

d 
#array([0, 2, 4, 6]) 
+0

Việc tìm kiếm hai lần làm chậm điều này một chút, tốt hơn là sử dụng 'C' đã biết để nhận' D'. Tuy nhiên, đây là giải pháp tốt hơn nếu 'C' là không cần thiết, vì vậy +1. (Chào mừng bạn đến với [SO]!) – askewchan

30

searchsorted có thể cung cấp cho bạn câu trả lời sai nếu không mọi phần tử của B là A. Bạn có thể sử dụng numpy.in1d:

A = np.array([1,2,3,4,5,6,7]) 
B = np.array([2,4,6,8]) 
mask = np.in1d(A, B) 
print np.where(mask)[0] 
print np.where(~mask)[0] 

đầu ra là:

[1 3 5] 
[0 2 4 6] 

Tuy nhiên in1d() sử dụng sắp xếp, chậm cho các tập dữ liệu lớn. Bạn có thể sử dụng gấu trúc nếu dữ liệu của bạn là lớn:

import pandas as pd 
np.where(pd.Index(pd.unique(B)).get_indexer(A) >= 0)[0] 

Đây là sự so sánh thời gian:

A = np.random.randint(0, 1000, 10000) 
B = np.random.randint(0, 1000, 10000) 

%timeit np.where(np.in1d(A, B))[0] 
%timeit np.where(pd.Index(pd.unique(B)).get_indexer(A) >= 0)[0] 

đầu ra:

100 loops, best of 3: 2.09 ms per loop 
1000 loops, best of 3: 594 µs per loop 
+2

Thật tuyệt khi biết về phương pháp hiệu quả này vì bộ dữ liệu của tôi rất lớn. Cảm ơn rất nhiều vì giải pháp này! – DanHickstein

2

Các yếu tố của A mà cũng nằm trong B:

đặt (A) & đặt (B)

Các yếu tố của A mà không phải là trong B:

bộ (A) - bộ (B)

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