2017-06-14 14 views
5
khác

Tôi có một mảng a = [1, 2, 3, 4, 5, 6]b = [1, 3, 5] và tôi muốn để lập bản đồ a như vậy mà cho mọi phần tử trong a đó là giữa một phần tử trong b nó sẽ được ánh xạ tới các chỉ số b đó là phạm vi trên mà a được chứa trong. Không phải là lời giải thích tốt nhất trong lời nói, nhưng đây là một ví dụPython - dễ dàng cách để "so sánh" bản đồ một mảng để

a = 1 -> 0 because a <= first element of b 
a = 2 -> 1 because b[0] < 2 <= b[1] and b[1] = 3 
a = 3 -> 1 
a = 4 -> 2 because b[1] < 4 <= b[2] 

Vì vậy, sản phẩm cuối cùng tôi muốn là f(a, b) = [0, 1, 1, 2, 2, 2]

tôi biết tôi chỉ vòng lặp và có thể giải quyết cho nó nhưng tôi đã tự hỏi nếu có một thông minh, nhanh chóng (vectorized) cách để làm điều này trong gấu trúc/NumPy

+0

có những mảng luôn ra lệnh? – taras

+0

Có, bạn có thể cho rằng chúng được đặt hàng.Cũng có thể giả định rằng mọi phần tử của b được chứa trong một (một giải pháp tổng quát hơn mà không có ràng buộc này sẽ là tuyệt vời, nhưng tôi nghĩ nó làm cho nó dễ dàng hơn) – Michael

Trả lời

7

bisect mô-đun Sử dụng python của:

from bisect import bisect_left 

a = [1, 2, 3, 4, 5, 6] 
b = [1, 3, 5] 

def f(_a, _b): 
    return [bisect_left(_b, i) for i in _a] 

print(f(a, b)) 

bisect - Thuật toán bisection Array

Mô-đun này cung cấp hỗ trợ để duy trì danh sách theo thứ tự được sắp xếp mà không phải sắp xếp danh sách sau mỗi lần chèn. Đối với danh sách dài các mục có hoạt động so sánh đắt tiền, điều này có thể là một cải tiến so với cách tiếp cận phổ biến hơn. Module này được gọi là bisect vì nó sử dụng một thuật toán bisection cơ bản để thực hiện công việc của nó. Mã nguồn có thể hữu ích nhất như là một ví dụ làm việc của thuật toán (các điều kiện biên đã đúng!).

Các chức năng sau đây được cung cấp:

bisect.bisect_left(a, x, lo=0, hi=len(a))

Xác định vị trí điểm chèn cho x trong một để duy trì trật tự sắp xếp. Các thông số lohi có thể được sử dụng để chỉ định một tập con của danh sách cần được xem xét; theo mặc định, toàn bộ danh sách được sử dụng. Nếu x đã có trong a, điểm chèn sẽ là trước (ở bên trái) bất kỳ mục nhập hiện có nào. Giá trị trả lại phù hợp để sử dụng làm tham số đầu tiên cho list.insert() giả định rằng a đã được sắp xếp.

Các trở điểm chèn i phân vùng mảng một thành hai nửa để all(val < x for val in a[lo:i]) cho phía bên trái và all(val >= x for val in a[i:hi]) cho phía bên phải.

tham khảo: https://docs.python.org/3/library/bisect.html

2

bisect là nhanh hơn: các giải pháp đảm nhận việc danh sách đều được sắp xếp

a = [1, 2, 3, 4, 5, 6] 
b = [1, 3, 5] 

inds=[min(bisect_left(b,x),len(b)-1) for x in a] 

lợi nhuận

[0, 1, 1, 2, 2, 2] 
Các vấn đề liên quan