Sounds like it could be a good match for `scipy.spatial.cKDTree`.<br><br>It can handle single-element queries...<br><br>>>> element = numpy.arange(1, 8)<br>>>> targets = numpy.random.uniform(0, 8, (1000, 7))<br>
>>> tree = scipy.spatial.cKDTree(targets)<br>>>> distance, index = tree.query(element)<br>>>> targets[index]<br>array([ 1.68457267,а 4.26370212,а 3.14837617,а 4.67616512,а 5.80572286,<br>ааааааа 6.46823904,а 6.12957534])<br>
<br>Or even multi-element queries (shown here searching for 3 elements in one call)...<br><div id=":144"></div><br>>>> elements = numpy.linspace(1, 8, 21).reshape((3, 7))<br>>>> elements<br>array([[ 1.а ,а 1.35,а 1.7 ,а 2.05,а 2.4 ,а 2.75,а 3.1 ],<br>
аааааа [ 3.45,а 3.8 ,а 4.15,а 4.5 ,а 4.85,а 5.2 ,а 5.55],<br>аааааа [ 5.9 ,а 6.25,а 6.6 ,а 6.95,а 7.3 ,а 7.65,а 8.а ]])<br>>>> distances, indices = tree.query(element)<br>
>>> targets[indices]<br>array([[ 0.24314961,а 2.77933521,а 2.00092505,а 3.25180563,а 2.05392726,<br>аааааааа 2.80559459,а 4.43030939],<br>аааааа [ 4.19270199,а 2.89257994,а 3.91366449,а 3.29262138,а 3.6779851 ,<br>
аааааааа 4.06619636,а 4.7183393 ],<br>аааааа [ 6.58055518,а 6.59232922,а 7.00473346,а 5.22612494,а 7.07170015,<br>аааааааа 6.54570121,а 7.59566404]])<br><br>Richard Hattersley<br><br><br><div class="gmail_quote">On 2 May 2012 19:06, Moroney, Catherine M (388D) <span dir="ltr"><<a href="mailto:Catherine.M.Moroney@jpl.nasa.gov" target="_blank">Catherine.M.Moroney@jpl.nasa.gov</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0pt 0pt 0pt 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">Hello,<br>
<br>
Can somebody give me some hints as to how to code up this function<br>
in pure python, rather than dropping down to Fortran?<br>
<br>
I will want to compare a 7-element vector (called "element") to a large list of similarly-dimensioned<br>
vectors (called "target", and pick out the vector in "target" that is the closest to "element"<br>
(determined by minimizing the Euclidean distance).<br>
<br>
For instance, in (slow) brute force form it would look like:<br>
<br>
element = numpy.array([1, 2, 3, 4, 5, 6, 7])<br>
target а= numpy.array(range(0, 49)).reshape(7,7)*0.1<br>
<br>
min_length = 9999.0<br>
min_index а=<br>
for i in xrange(0, 7):<br>
а distance = (element-target)**2<br>
а distance = numpy.sqrt(distance.sum())<br>
а if (distance < min_length):<br>
а а аmin_length = distance<br>
а а аmin_index а= i<br>
<br>
Now of course, the actual problem will be of a much larger scale. аI will have<br>
an array of elements, and a large number of potential targets.<br>
<br>
I was thinking of having element be an array where each element itself is<br>
a numpy.ndarray, and then vectorizing the code above so as an output I would<br>
have an array of the "min_index" and "min_length" values.<br>
<br>
I can get the following simple test to work so I may be on the right track:<br>
<br>
import numpy<br>
<br>
dtype = [("x", numpy.ndarray)]<br>
<br>
def single(data):<br>
а аreturn data.min()<br>
<br>
multiple = numpy.vectorize(single)<br>
<br>
if __name__ == "__main__":<br>
<br>
а аa = numpy.arange(0, 16).reshape(4,4)<br>
а аb = numpy.recarray((4), dtype=dtype)<br>
а аfor i in xrange(0, b.shape):<br>
а а а аb[i]["x"] = a[i,:]<br>
<br>
а аprint a<br>
а аprint b<br>
<br>
а аx = multiple(b)<br>
а аprint x<br>
<br>
What is the best way of constructing "b" from "a"? аI tried b = numpy.recarray((4), dtype=dtype, buf=a)<br>
but I get a segmentation fault when I try to print b.<br>
<br>
Is there a way to perform this larger task efficiently with record arrays and vectorization, or<br>
am I off on the wrong track completely? аHow can I do this efficiently without dropping<br>
down to Fortran?<br>
<br>