2016-11-29 15 views
5

Tôi đã có một danh sách các tọa độ 2d với cấu trúc này:Cách nào hiệu quả hơn để chọn một cặp đối tượng ngẫu nhiên từ danh sách các danh sách hoặc bộ dữ liệu?

coo = [(0, 0), (0, 1), (0, 2), (1, 0), (1, 1), (1, 2), (2, 0)] 

đâu coo[0] được tọa độ đầu tiên được lưu giữ trong một tuple.

Tôi muốn chọn hai số khác nhau tọa độ ngẫu nhiên. Tôi tất nhiên có thể sử dụng phương pháp này:

import numpy as np 
rndcoo1 = coo[np.random.randint(0,len(coo))] 
rndcoo2 = coo[np.random.randint(0,len(coo))] 
if rndcoo1 != rndcoo2: 
    #do something 

Nhưng bởi vì tôi phải lặp lại thao tác này 1'000'000 lần tôi đã tự hỏi nếu có một phương pháp nhanh hơn để làm điều đó. np.random.choice() không thể được sử dụng cho mảng 2d là có bất kỳ thay thế mà tôi có thể sử dụng?

+1

là 'coo' thực sự là một mảng NumPy? Bạn đã thử 'random.choice' thay vì' np.random.choice' chưa? Và 'rndcoo1' và 'rndcoo2' có khác biệt không? –

+0

@ G M rndcoo1, rndcoo2 = [coo [np.random.choice (len (coo))] cho __ trong phạm vi (2)] –

+0

@tobias_k coo có thể là danh sách nếu cần. Trên thực tế tôi không biết random.choice có thể được sử dụng và nó có vẻ tốt hơn. Tôi phải chọn hai tọa độ khác nhau không thể giống nhau. –

Trả lời

6
import random 
result = random.sample(coo, 2) 

sẽ cung cấp cho bạn kết quả mong đợi. Và nó là (có thể) nhanh như bạn có thể nhận được với Python.

0

Có phải coo chỉ là ví dụ hoặc tọa độ của bạn thực sự có khoảng cách bằng nhau không? Nếu vậy, bạn chỉ có thể lấy mẫu M 2D-tọa độ như thế này:

import numpy 

N = 100 
M = 1000000 
coo = numpy.random.randint(0, N, size=(M, 2)) 

Tất nhiên bạn cũng có thể thiên vị và quy mô phân phối sử dụng cộng và phép nhân để giải thích cho kích thước bước khác nhau và bù đắp.

Nếu bạn gặp giới hạn bộ nhớ với số lớn M s, bạn có thể lấy mẫu kích thước nhỏ hơn hoặc chỉ một mảng gồm 2 giá trị với size=2.

1

Được liệt kê trong bài đăng này là phương pháp được vector hóa giúp chúng tôi có một số lựa chọn ngẫu nhiên như vậy cho một số lần lặp lại trong một lần mà không lặp qua nhiều lần lặp lại đó. Ý tưởng sử dụng np.argpartition và được lấy cảm hứng từ this post.

Đây là việc thực hiện -

def get_items(coo, num_items = 2, num_iter = 10): 
    idx = np.random.rand(num_iter,len(coo)).argpartition(num_items,axis=1)[:,:2] 
    return np.asarray(coo)[idx] 

Xin lưu ý rằng chúng tôi sẽ trả về một mảng 3D với kích thước đầu tiên là số lần lặp lại, chiều thứ hai là số lựa chọn để được thực hiện tại mỗi lần lặp và cuối cùng kích thước là chiều dài của mỗi bộ.

Một chạy mẫu nên trình bày một chút hình ảnh rõ ràng hơn -

In [55]: coo = [(0, 0), (0, 1), (0, 2), (1, 0), (1, 1), (1, 2), (2, 0)] 

In [56]: get_items(coo, 2, 5) 
Out[56]: 
array([[[2, 0], 
     [1, 1]], 

     [[0, 0], 
     [1, 1]], 

     [[0, 2], 
     [2, 0]], 

     [[1, 1], 
     [1, 0]], 

     [[0, 2], 
     [1, 1]]]) 

Runtime thử nghiệm so sánh việc thực hiện điên rồ với random.sample được liệt kê trong @freakish's post -

In [52]: coo = [(0, 0), (0, 1), (0, 2), (1, 0), (1, 1), (1, 2), (2, 0)] 

In [53]: %timeit [random.sample(coo, 2) for i in range(10000)] 
10 loops, best of 3: 34.4 ms per loop 

In [54]: %timeit get_items(coo, 2, 10000) 
100 loops, best of 3: 2.81 ms per loop 
+0

tuyệt vời! Công việc rất thú vị! –

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