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[0].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[0]):<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>
Thanks for any advice,<br>
<br>
Catherine<br>
_______________________________________________<br>
NumPy-Discussion mailing list<br>
<a href="mailto:NumPy-Discussion@scipy.org">NumPy-Discussion@scipy.org</a><br>
<a href="http://mail.scipy.org/mailman/listinfo/numpy-discussion" target="_blank">http://mail.scipy.org/mailman/listinfo/numpy-discussion</a><br>
</blockquote></div><br>