0
votes

With an global distributed variable in the shape of (len(latitude), len(longitude)), I want to get an subset corresponding to the area of interest.

The specific area is defined by 2 corners(left-low latitude/longitude, right-top latitude/longitude). So, this array is what I have now:

  • VALUE is a 2-d array representing the global distribution

  • Lon is a 1-d array from (-180.0, 179.875) owning 2880 elements

  • Lat is a 1-d array from (-90, 89.875) owning 1440 elements.

  • llcrnrlat, urcrnrlat, llcrnrlon, urcrnrlon = 15, 50, 90, 150

Noticing that the llcrnrlat etc may not contain in the Lon or Lat, I can't use

 VALUE_SELECT = VALUE[np.where(Lat ==llcrnrlat):np.where(Lat ==urcrnrlat),
                      np.where(Lon ==urcrnrlat):np.where(Lon ==urcrnrlat)]

So, my attempt is to loop the Lat and Lon aiming to find the indice for nearest value.

def find_nearest(array,value): ## This function was clipped from website
    idx = (np.abs(array-value)).argmin()
    return array[idx]
llcrnrlon,urcrnrlon = 90,150
llcrnrlat, urcrnrlat = 15, 50

nx_st = np.where(lon == (find_nearest(lon,llcrnrlon )))[0]
nx_en = np.where(lon == (find_nearest(lon,urcrnrlon )))[0]
ny_st = np.where(lat == (find_nearest(lat,llcrnrlat )))[0]
ny_en = np.where(lat == (find_nearest(lat,urcrnrlat )))[0]

lon_select,lat_select = lon[nx_st:nx_en+1], lat[ny_st:ny_en+1]
value_select  =VALUE[ny_st:ny_en+1,nx_st:nx_en+1]    

After execute these subroutine, there is an warning right here:

/Users/anaconda/lib/python2.7/site-packages/ipykernel/main.py:1: VisibleDeprecationWarning: converting an array with ndim > 0 to an index will result in an error in the future if name == 'main':

  • How to avoid this warning or potential error?
  • Is there any easier way to get an subset of 2-d array based on my case?
1
Are the values evenly distributed in Lon and Lat? If yes, you don't need to look them up in the array to find their index. Just round(1439 * (llcrnrlat + 90) / 179.875) for exampletschundler
Yes, the values are evenly distributed.Han Zhengzu

1 Answers

1
votes

That find_nearest + np.where is a whole lot of computational work that is completely unneeded if the values are evenly distributed. Do you really understand what that code is doing? Read up on each of those functions. You're doing a subtraction on every value in an array, and then finding the index of the minimum of that offset. Then you look up the value at that minimum. Then with the value, you again look through every value in the array and test if it matches, creating a new array of True/False values. Then you sort through that array and find the index of what was True. The same index you already found with argmin()

Each lat/lon is split into 8 sections. So you just need to multiply by 8, right? Then make it an integer, which automatically applies a floor()

function lat_conv(y):
    return int((y + 90) * 8)
function lon_conv(x):
    return int((x + 180) * 8)

value_select = VALUES[lon_conv(start_lon):lon_conv(stop_lon),
                      lat_conv(start_lat):lat_conv(stop_lat)]