Domanda

In Pythons Numpy module, is there a function that can calculate long/advanced math expressions on an array? I heard of the numexp module but want to stay clear of further dependencies.

Better yet, can I limit these expressions to only say the first or second element of the sub arrays within my array, without having to unpack them as separate arrays?

Here is my specific problem. I have an array of arrays containing geographic point coordinates looking like this: [[x1,y1],[x2,y2],[x3,y3],etc...]. What I want is to transform these geocoords to pixel coordinates so they can be drawn on an image. I therefore want to run the following expression/calculation on the first element of each subarray, ie the xs:

((180+X)/360)*screenwidthpixels

And on the second element, ie the ys:

((-90+Y)/180)*-screenheightpixels

These expressions would work in a python for-loop but is too slow, which is why I'm turning to Numpy. I know I can and have tried to just link numpys single math operator functions after each other but still too slow, and besides, to do that I first had to unpack all the xs and ys to separate arrays and repack them together after the calculation making it even slower.

So I guess I'm looking for a more direct Numpy way using less steps to transform my coordinate array using the expressions above. Any ideas?

È stato utile?

Soluzione

import numpy as np
points = np.random.rand(10,2)
translation = np.array([180,-90])
scaling = np.array([1024, -768]) / np.array([360,180])
transformed_points = (points + translation) * scaling

This will do what you are looking for. It relies on numpy broadcasting rules to achieve expressiveness and performance.

But rather than explaining exactly how that works, I think you are better off finding yourself a good numpy primer, and starting at the top. numpy is one of the best things about python, and you cant go wrong learning a little more about it. Suffice to say, numpy is certainly up to the kind of task you are facing.

Altri suggerimenti

I'm a little confused because I'm not sure exactly what you're saying you already tried, or what the speed condition for success is.

Are you saying you already tried something like the following, but it is too slow?

arr = whatever
arr[:,0] = (arr[:,0] + 180) / (360 * screenwidthpixels)
arr[:,1] = 180 - (arr[:,1] - 90) / (180 * screenheightpixels)

I'm not sure what you mean by "having to unpack" to X and Y. Here's how you avoid unpacking (if i understand...)

arr = np.array([ [x1,y1], [x2,y2], [x3,y3] ])
arr.shape
=> (3, 2)
X = arr[:,0]  # fast, creates a view
Y = arr[:,1]  # fast too
((X+180)/360)/screenwidthpixels

Further speed up can be achieved by rewriting/simplifying your expressions.

((X+180)/360)/s       =>  (X+180)/(360*s)
(180-((Y+90)/180))/s  =>  (180/s-1/(2*s)) - y/(180*s)

In the first rewrite, you get 2 traverses of the array, instead of 3, and in the second, the array is only traversed twice, instead of 4 times.

In [235]: xs=arange(1000)

In [236]: ys=arange(1, 1001)

In [237]: a=array([xs, ys]).T

In [238]: a
Out[238]: 
array([[   0,    1],
       [   1,    2],
       [   2,    3],
       ..., 
       [ 997,  998],
       [ 998,  999],
       [ 999, 1000]])


In [240]: a[:, 0]=(a[:, 0]+180)/360/1024

the a[:, 0] offers a view of the first column of a, it's fast and memory saving. docs for numpy here

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top