简体   繁体   English

从 N 和 M 大小的 2 个数组/列表创建 NxM 数组

[英]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.

相关问题 将NxM numpy数组转换为(N * M)x1 - Convert NxM numpy array to (N*M)x1 如何从 numpy 数组创建 NxM 矩阵? - How to create NxM matrix from numpy array? 如何从 2 个维度 (m, n) 和 (n) 的数组中更好地执行 Pearson R,返回一个 (m) 大小的数组? [Python、NumPy、SciPy] - How better perform Pearson R from 2 arrays of dimensions (m, n) and (n), returning an array of (m) size? [Python, NumPy, SciPy] 如何从9个大小为N的阵列快速创建N 3x3矩阵阵列? - How to rapidly create array of N 3x3 matrices from 9 arrays of size N? n * m * 3输入图像到PyTorch中的nxm标签 - n*m*3 input image to an nxm label in PyTorch 创建N个长度为M的数组,其中每个数组的序列加1 - Create N arrays of length M where the sequence is increased by 1 on each array 从数组和 boolean “共享”数组创建 m*n arrays - Creating m*n arrays from an array and a boolean "shared" array 尝试使用列表创建大小为 m*n 的零矩阵,但我无法以所需的形状打印 output - Trying to create a zero matrix of size m*n using lists but I'm unable to print the output in desired shape 对于NxM数组,编写一个函数,使其在用户输入为(x,y)时应返回从(0,0)到(x,y)的所有值的总和。 其中x - For NxM array , Write a function such that if user input is (x,y) It should return a sum of all values from (0,0) to (x,y). where x<N & y<M 将大小为(n,n,m)的数组转换为(None,n,n,m) - converting an array of size (n,n,m) to (None,n,n,m)
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM