x 및 y 좌표의 numpy 배열에서 가장 가까운 지점의 색인 찾기
두 개의 2d numpy 배열이 있습니다. x_array는 x 방향의 위치 정보를 포함하고 y_array는 y 방향의 위치를 포함합니다.
그런 다음 x, y 포인트의 긴 목록이 있습니다.
목록의 각 지점에 대해 해당 지점에 가장 가까운 위치 (배열에 지정됨)의 배열 인덱스를 찾아야합니다.
이 질문을 기반으로 작동하는 코드를 순진하게 생성 했습니다 .numpy 배열에서 가장 가까운 값 찾기
즉
import time
import numpy
def find_index_of_nearest_xy(y_array, x_array, y_point, x_point):
distance = (y_array-y_point)**2 + (x_array-x_point)**2
idy,idx = numpy.where(distance==distance.min())
return idy[0],idx[0]
def do_all(y_array, x_array, points):
store = []
for i in xrange(points.shape[1]):
store.append(find_index_of_nearest_xy(y_array,x_array,points[0,i],points[1,i]))
return store
# Create some dummy data
y_array = numpy.random.random(10000).reshape(100,100)
x_array = numpy.random.random(10000).reshape(100,100)
points = numpy.random.random(10000).reshape(2,5000)
# Time how long it takes to run
start = time.time()
results = do_all(y_array, x_array, points)
end = time.time()
print 'Completed in: ',end-start
저는 대규모 데이터 세트에 대해이 작업을 수행하고 있으며 속도를 조금 높이고 싶습니다. 누구든지 이것을 최적화 할 수 있습니까?
감사.
업데이트 : @silvado 및 @justin (아래)의 제안에 따른 솔루션
# Shoe-horn existing data for entry into KDTree routines
combined_x_y_arrays = numpy.dstack([y_array.ravel(),x_array.ravel()])[0]
points_list = list(points.transpose())
def do_kdtree(combined_x_y_arrays,points):
mytree = scipy.spatial.cKDTree(combined_x_y_arrays)
dist, indexes = mytree.query(points)
return indexes
start = time.time()
results2 = do_kdtree(combined_x_y_arrays,points_list)
end = time.time()
print 'Completed in: ',end-start
This code above sped up my code (searching for 5000 points in 100x100 matrices) by 100 times. Interestingly, using scipy.spatial.KDTree (instead of scipy.spatial.cKDTree) gave comparable timings to my naive solution, so it is definitely worth using the cKDTree version...
scipy.spatial also has a k-d tree implementation: scipy.spatial.KDTree.
The approach is generally to first use the point data to build up a k-d tree. The computational complexity of that is on the order of N log N, where N is the number of data points. Range queries and nearest neighbour searches can then be done with log N complexity. This is much more efficient than simply cycling through all points (complexity N).
Thus, if you have repeated range or nearest neighbor queries, a k-d tree is highly recommended.
Here is a scipy.spatial.KDTree example
In [1]: from scipy import spatial
In [2]: import numpy as np
In [3]: A = np.random.random((10,2))*100
In [4]: A
Out[4]:
array([[ 68.83402637, 38.07632221],
[ 76.84704074, 24.9395109 ],
[ 16.26715795, 98.52763827],
[ 70.99411985, 67.31740151],
[ 71.72452181, 24.13516764],
[ 17.22707611, 20.65425362],
[ 43.85122458, 21.50624882],
[ 76.71987125, 44.95031274],
[ 63.77341073, 78.87417774],
[ 8.45828909, 30.18426696]])
In [5]: pt = [6, 30] # <-- the point to find
In [6]: A[spatial.KDTree(A).query(pt)[1]] # <-- the nearest point
Out[6]: array([ 8.45828909, 30.18426696])
#how it works!
In [7]: distance,index = spatial.KDTree(A).query(pt)
In [8]: distance # <-- The distances to the nearest neighbors
Out[8]: 2.4651855048258393
In [9]: index # <-- The locations of the neighbors
Out[9]: 9
#then
In [10]: A[index]
Out[10]: array([ 8.45828909, 30.18426696])
If you can massage your data into the right format, a fast way to go is to use the methods in scipy.spatial.distance:
http://docs.scipy.org/doc/scipy/reference/spatial.distance.html
In particular pdist and cdist provide fast ways to calculate pairwise distances.
'program story' 카테고리의 다른 글
| “Project Navigator”패널에서 XCode 4에서 열린 파일을 강조 표시하는 방법은 무엇입니까? (0) | 2020.11.19 |
|---|---|
| phonegap / cordova를 사용하는 동안 'node'는 내부 또는 외부 명령, 작동 가능한 프로그램 또는 배치 파일로 인식되지 않습니다. (0) | 2020.11.19 |
| pandas.read_csv를 가져 와서 빈 값을 nan 대신 빈 문자열로 읽습니다. (0) | 2020.11.18 |
| Tomcat-maxThreads 대 maxConnections (0) | 2020.11.18 |
| PHP에서 배열의 최대 키 크기는 얼마입니까? (0) | 2020.11.18 |