Numpy:将函数应用于两个Numpy数组并返回两个Numpy数组。

3

我有两个输入的numpy数组,分别是一组点的纬度和经度坐标:latslons

我继承了一个将每个(lat,lon)对转换为(E,N)对的函数:

def convert(lat,lon): #takes two floats as arguments (unit: degrees)
   ...
   computation #Actual function is too long to post
   ...
   return N,E #returns two floats (unit: meters)

我的问题:如何高效地同时将相同的函数应用于两个输入的numpy数组?

我考虑修改该函数,使其返回一个列表:

return [N,E] 

以这种方式:
rows = int(lat.shape[0]) #lat and lon have the same shape
cols = int(lat.shape[1])
easting=numpy.zeros(shape=(rows,cols))
northing=numpy.zeros(shape=(rows,cols))
for i in range(0, rows):
    for j in range(0, cols):
        northing=convert(lon[i][j])[0] #first element of the returned list
        easting=convert(lat[i][j])[1] #second element of the returned list

我还没有测试过,但是通过观察,我不太确定这个能否正常工作。非常感谢任何见解。


这将取决于convert函数的细节。它可能已经按照你想要的方式正常工作,或者你可能需要将math.sin切换为np.sin之类的操作,或者如果代码依赖于无法控制或替换的API,并且每次只处理一对元素,那么有效地完成此操作可能基本上是不可能的。 - undefined
1个回答

4

让我们定义一个简单的转换

def convert(lat, lon):
    return lat*np.pi/180, lon*np.pi/180

frompyfunc是一种将“标量”函数应用于数组的有用方法;我们甚至可以让它接受2个数组,并返回2个数组(以元组形式)。

In [233]: f = np.frompyfunc(convert,2,2)
In [234]: lats=np.linspace(-45,45,5)
In [235]: lons=np.linspace(0,100,5)
In [236]: out = f(lats, lons)
In [237]: out
Out[237]: 
(array([-0.7853981633974483, -0.39269908169872414, 0.0, 0.39269908169872414,
        0.7853981633974483], dtype=object),
 array([0.0, 0.4363323129985824, 0.8726646259971648, 1.3089969389957472,
        1.7453292519943295], dtype=object))

其中一个特点是它返回一个对象数组,而你可能需要一个浮点数数组:

In [238]: out[0].astype(float)
Out[238]: array([-0.78539816, -0.39269908,  0.        ,  0.39269908,  0.78539816])

或者使用解压方式:
In [239]: rlat, rlon = f(lats, lons)
In [240]: rlat.astype(float)
Out[240]: array([-0.78539816, -0.39269908,  0.        ,  0.39269908,  0.78539816])
frompyfunc会迭代处理输入。在其他测试中,它往往比更明确的循环快2倍。而且在这种情况下,由于它返回一个元组,您不必调用两次以获取2个结果。
如所写的那样,这个convert函数对数组和标量都同样适用,因此
In [241]: convert(lats, lons)
Out[241]: 
(array([-0.78539816, -0.39269908,  0.        ,  0.39269908,  0.78539816]),
 array([ 0.        ,  0.43633231,  0.87266463,  1.30899694,  1.74532925]))

这将比在Python中循环的任何版本都要快得多。

因此,为了获得真正的速度,您希望convert直接使用数组。但如果无法做到这一点,那么frompyfunc比自行循环略有改进。

frompyfunc的另一个优点是它应用了数组广播,例如

 f( lats[:,None], lons[None,:])

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接