[英]Create NxM array from 2 arrays/lists of N and M size
I have longitude and latitude arrays of fixed resolutions ie .1.我有固定分辨率的经度和纬度数组,即 .1。 This gives me 1800 lats and 3600 lons.这给了我 1800 lats 和 3600 lons。 I want to create a matrix of 1800x 3600 that will store area for each grid based on the formula here .我想创建一个 1800x 3600 的矩阵,它将根据此处的公式存储每个网格的区域。 ie IE
A = 2 pi R^2 |sin(lat1)-sin(lat2)| A = 2 pi R^2 |sin(lat1)-sin(lat2)| |lon1-lon2|/360 |lon1-lon2|/360
I have lons are lats already in arrays which represents centre of the grid.我有 lons 已经在代表网格中心的数组中。 Currently I use a formula, which calculates area for a given rectangle box.目前我使用一个公式,它计算给定矩形框的面积。
def grid_area(lat1, lon1, lat2, lon2, radius= 6365000):
"""
Calculate grid area based on lat-long points of rectangle/square grid size by degrees.
Calculations are without any prohection system.
radius in meters is used to make it generic. Defaults to Earth
Formuala from : https://www.pmel.noaa.gov/maillists/tmap/ferret_users/fu_2004/msg00023.html
"""
import numpy as np
area = (np.pi/180)*(radius**2) *np.abs(np.sin(np.radians(lat1)) - np.sin(np.radians(lat2))) * np.abs(lon1 -lon2)/360
return area
I use this in a double loop for each lat/lon combination to get the area_grid.我在每个纬度/经度组合的双循环中使用它来获取 area_grid。
grid_areas = np.zeros((len(lats), len(longs)))
for ll in range(len(longs)-1):
for lt in range(len(lats)-1):
lt1 = np.round(lats[lt]+.05,2)
ll1 = np.round(longs[ll]-.05,2)
lt2 = np.round(lats[lt]-.05,2)
ll2 = np.round(longs[ll]+.05,2)
grid_areas[lt,ll] = grid_area(lt1,ll1,lt2,ll2)
This as expected is slow.正如预期的那样,这很慢。 I am not sure which approach I can use to make it efficient.我不确定我可以使用哪种方法来提高效率。 I looked through the forum to create NxM matrixes, but not able to get the solution for this problem.我浏览了论坛以创建 NxM 矩阵,但无法获得此问题的解决方案。
While writing this question, came across this thread on stackoverflow to use itertools.chain .在写这个问题时, 在 stackoverflow 上遇到了这个线程来使用 itertools.chain 。 Will try to change my code as per this, if that helps.如果有帮助,将尝试按照此更改我的代码。 Will update my findings on that.将更新我的发现。
In the meantime, any help in the right direction would help.与此同时,任何朝着正确方向的帮助都会有所帮助。
UPDATE : I changed my code using itertools.product更新:我使用 itertools.product 更改了我的代码
lat_longs = np.array(list(itertools.product(*[lats.tolist(),longs.tolist()])))
and updated the function to accept centroids.并更新函数以接受质心。
def grid_area(lat=None, lon=None, grid_size=.1, radius= 6365000):
"""
Calculate grid area based on lat-long points of rectangle/square grid size by degrees.
Calculations are without any prohection system.
radius in meters is used to make it generic. Defaults to Earth
Formuala from : https://www.pmel.noaa.gov/maillists/tmap/ferret_users/fu_2004/msg00023.html
"""
import numpy as np
grid_delta = grid_size/2
lat1 = lat+grid_delta
lat2 = lat-grid_delta
lon1 = lon - grid_delta
lon2 = lon + grid_delta
area = (np.pi/180)*(radius**2) *np.abs(np.sin(np.radians(lat1)) - np.sin(np.radians(lat2))) * np.abs(lon1 -lon2)/360
return area
I then rearrange the return area array using然后我使用重新排列返回区域数组
areas_mat = areas.reshape((lats.shape[0], longs.shape[0]))
Now the longest part of the code is the itertools.product.现在代码中最长的部分是 itertools.product。 it takes about 4.5 seconds, while the area calculation takes only about 350ms.大约需要4.5秒,而面积计算只需要大约350ms。
Any other way to get that first combination faster?还有其他方法可以更快地获得第一个组合吗?
You can trivially vectorize this operation across all your arrays.您可以在所有数组中轻松矢量化此操作。 Given an array lats
with shape (1800,)
, and an array lons
with shape (3600,)
, you can reshape them so that the broadcasted computation yields an array of the correct shape.给定一个形状为(1800,)
的数组lats
和一个形状为(3600,)
的数组lons
,您可以对它们进行整形(3600,)
以便广播计算产生一个正确形状的数组。
grid_delta = 0.5 * grid_size
# dlon: (3600,)
dlon = np.full(lons.shape, grid_size / 360)
# dlat: (1800, 1)
dlat = np.abs(np.sin(np.deg2rad(lats + grid_delta)) -
np.sin(np.deg2rad(lats - grid_delta)))[:, None]
# area: (1800, 3600)
area = np.rad2deg(radius**2 * dlat * dlon / 360)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.