Tôi có lưới điện/vĩ độ không đều (không hình chữ nhật) và một số điểm trong tọa độ lon/vĩ độ, tương ứng với các điểm trên lưới (mặc dù chúng có thể hơi tắt vì lý do số). Bây giờ tôi cần các chỉ số của các điểm lon/lat tương ứng.Hiệu quả tìm thấy các chỉ số của các điểm gần nhất trên lưới 2D không phải hình chữ nhật
Tôi đã viết một chức năng thực hiện điều này, nhưng nó thực sự chậm.
def find_indices(lon,lat,x,y):
lonlat = np.dstack([lon,lat])
delta = np.abs(lonlat-[x,y])
ij_1d = np.linalg.norm(delta,axis=2).argmin()
i,j = np.unravel_index(ij_1d,lon.shape)
return i,j
ind = [find_indices(lon,lat,p*) for p in points]
Tôi chắc rằng có một giải pháp tốt hơn (và nhanh hơn) trong gọn gàng/scipy. Tôi đã googled khá nhiều, nhưng câu trả lời đã cho đến nay eluded tôi.
Bất kỳ đề xuất nào về cách tìm hiệu quả các chỉ số của các điểm tương ứng (gần nhất)?
PS: Câu hỏi này nổi lên từ một câu hỏi khác (click).
Edit: Giải pháp
Dựa trên câu trả lời @Cong Ma, tôi đã tìm thấy các giải pháp sau đây:
def find_indices(points,lon,lat,tree=None):
if tree is None:
lon,lat = lon.T,lat.T
lonlat = np.column_stack((lon.ravel(),lat.ravel()))
tree = sp.spatial.cKDTree(lonlat)
dist,idx = tree.query(points,k=1)
ind = np.column_stack(np.unravel_index(idx,lon.shape))
return [(i,j) for i,j in ind]
Để đưa giải pháp này và cũng là một từ câu trả lời Divakar của thành quan điểm, đây là một số thời gian của hàm mà tôi đang sử dụng find_indices (và nơi nó là nút cổ chai về tốc độ) (xem liên kết ở trên):
spatial_contour_frequency/pil0 : 331.9553
spatial_contour_frequency/pil1 : 104.5771
spatial_contour_frequency/pil2 : 2.3629
spatial_contour_frequency/pil3 : 0.3287
pil0
là cách tiếp cận ban đầu của tôi, pil1
Divakar's và pil2
/pil3
giải pháp cuối cùng ở trên, nơi cây được tạo trực tiếp trong pil2
(tức là cho mỗi lần lặp của vòng lặp trong đó find_indices
được gọi) và chỉ một lần trong pil3
(xem các chủ đề khác để biết chi tiết). Mặc dù sự tinh chỉnh của Divakar về cách tiếp cận ban đầu của tôi mang lại cho tôi tốc độ gấp 3 lần, cKDTree mang đến một cấp độ hoàn toàn mới với tốc độ 50 lần khác! Và di chuyển việc tạo ra cây ra khỏi chức năng làm cho mọi việc nhanh hơn.
Trong tập lệnh, bạn đang tạo một cây mới với mỗi lệnh gọi đến 'find_indices'. Nếu lưới của bạn được cố định qua các cuộc gọi, bạn đang lãng phí thời gian xây dựng cùng một cây hơn và hơn nữa. Trên thực tế việc xây dựng cây này là một cuộc gọi chậm nhất trong chức năng này. –
Vâng, tôi đã nhận thấy, đó là những gì tôi đang làm việc vào lúc này. ;) Tôi sẽ cập nhật câu trả lời cho phù hợp. Cảm ơn nhận xét. – flotzilla