【问题标题】:Numpy: apply function to two numpy arrays and return two numpy arraysNumpy:将函数应用于两个numpy数组并返回两个numpy数组
【发布时间】:2017-03-11 20:05:33
【问题描述】:

我有两个输入 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,则基本上不可能有效地完成它一次替换一对元素。

标签: python arrays function loops numpy


【解决方案1】:

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

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,:])

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-09-19
    • 1970-01-01
    • 2018-04-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多