Python:将坐标从列表传递到函数

Python: passing coordinates from list to function

我正在使用 workshop 中的一些代码按最接近我指定坐标的坐标从 netCDF 文件中提取数据。当只使用一组坐标时,我可以毫无困难地提取我需要的值,如下所示:

import numpy as np
import netCDF4
from math import pi
from numpy import cos, sin

def tunnel_fast(latvar,lonvar,lat0,lon0):
    '''
    Find closest point in a set of (lat,lon) points to specified point
    latvar - 2D latitude variable from an open netCDF dataset
    lonvar - 2D longitude variable from an open netCDF dataset
    lat0,lon0 - query point
    Returns iy,ix such that the square of the tunnel distance
    between (latval[it,ix],lonval[iy,ix]) and (lat0,lon0)
    is minimum.
    '''

    rad_factor = pi/180.0 # for trignometry, need angles in radians
    # Read latitude and longitude from file into numpy arrays
    latvals = latvar[:] * rad_factor
    lonvals = lonvar[:] * rad_factor
    ny,nx = latvals.shape
    lat0_rad = lat0 * rad_factor
    lon0_rad = lon0 * rad_factor
    # Compute numpy arrays for all values, no loops
    clat,clon = cos(latvals),cos(lonvals)
    slat,slon = sin(latvals),sin(lonvals)
    delX = cos(lat0_rad)*cos(lon0_rad) - clat*clon
    delY = cos(lat0_rad)*sin(lon0_rad) - clat*slon
    delZ = sin(lat0_rad) - slat;
    dist_sq = delX**2 + delY**2 + delZ**2
    minindex_1d = dist_sq.argmin()  # 1D index of minimum element
    iy_min,ix_min = np.unravel_index(minindex_1d, latvals.shape)
    return iy_min,ix_min

ncfile = netCDF4.Dataset('E:\wind_level2_1.nc', 'r')
latvar = ncfile.variables['latitude']
lonvar = ncfile.variables['longitude']

#_________GG turbine_________GAD10  Latitude    51.735516, GAD10    Longitude   1.942656

iy,ix = tunnel_fast(latvar, lonvar, 51.735516, 1.942656)
print('Closest lat lon:', latvar[iy,ix], lonvar[iy,ix])

refLAT=latvar[iy,ix]
refLON = lonvar[iy,ix]
#try to find the data for this location

SARwind = ncfile.variables['sar_wind'][:,:]
ModelWind = ncfile.variables['model_speed'][:,:]

print 'iy,ix' #appears to be the index of the value of Lat,lon
print SARwind[iy,ix]


ncfile.close()

现在我正在尝试遍历包含坐标 coord_list 的文本文件以提取坐标集,找到数据然后移动到列表中的下一组坐标。此代码可独立运行,如下所示:

import csv
from decimal import Decimal
with open('Turbine_locs_no_header.csv','rb') as f:
    reader = csv.reader(f)
    #coord_list = list(reader)
    coord_list = [reader]
    end_row = len(coord_list)

    lon_ind=1
    lat_ind=2

for row in range(0, end_row-1):#end_row - 1 due to the 0 index
    turbine_lat = coord_list[row][lat_ind]
    turbine_lon = coord_list[row][lon_ind]
    turbine_lat = [Decimal(turbine_lat)]
    print 'lat',turbine_lat, 'lon',turbine_lon, row

但是,我想将文本文件中的坐标传递给这部分原始代码iy,ix = tunnel_fast(latvar, lonvar, 51.94341, 1.922094888),用变量iy, ix = tunnel_fast(latvar, lonvar, turbine_lat, turbine_lon)替换数字。我尝试通过创建一个函数 get_coordinates 来组合这两个代码,我得到以下错误

  File "C:/Users/mm/test_nc_bycoords_GG_turbines_AGW.py", line 65, in <module>
    get_coordinates(coord_list, latvar, lonvar)
  File "C:/Users/mm/test_nc_bycoords_GG_turbines_AGW.py", line 51, in get_coordinates
    iy, ix = tunnel_fast(latvar, lonvar, turbine_lat, turbine_lon)
  File "C:/Users/mm/test_nc_bycoords_GG_turbines_AGW.py", line 27, in tunnel_fast
    lat0_rad = lat0 * rad_factor
TypeError: can't multiply sequence by non-int of type 'float'

我认为这是因为 turbine_latturbine_lon 是列表项所以不能使用,但这似乎与错误无关。我知道这段代码无论如何都需要做更多的工作,但如果有人能帮助我找出我出错的地方,那将非常有帮助。我尝试结合这两个代码如下。

import numpy as np
import netCDF4
from math import pi
from numpy import cos, sin
import csv

# edited from https://github.com/Unidata/unidata-python-workshop/blob/a56daa50d7b343c7debe93968683613642d6b9f7/notebooks/netcdf-by-coordinates.ipynb

def tunnel_fast(latvar,lonvar,lat0,lon0):
    '''
    Find closest point in a set of (lat,lon) points to specified point
    latvar - 2D latitude variable from an open netCDF dataset
    lonvar - 2D longitude variable from an open netCDF dataset
    lat0,lon0 - query point
    Returns iy,ix such that the square of the tunnel distance
    between (latval[it,ix],lonval[iy,ix]) and (lat0,lon0)
    is minimum.
    '''

    rad_factor = pi/180.0 # for trignometry, need angles in radians
    # Read latitude and longitude from file into numpy arrays
    latvals = latvar[:] * rad_factor
    lonvals = lonvar[:] * rad_factor
    ny,nx = latvals.shape
    lat0_rad = lat0 * rad_factor
    lon0_rad = lon0 * rad_factor
    # Compute numpy arrays for all values, no loops
    clat,clon = cos(latvals),cos(lonvals)
    slat,slon = sin(latvals),sin(lonvals)
    delX = cos(lat0_rad)*cos(lon0_rad) - clat*clon
    delY = cos(lat0_rad)*sin(lon0_rad) - clat*slon
    delZ = sin(lat0_rad) - slat;
    dist_sq = delX**2 + delY**2 + delZ**2
    minindex_1d = dist_sq.argmin()  # 1D index of minimum element
    iy_min,ix_min = np.unravel_index(minindex_1d, latvals.shape)
    return iy_min,ix_min
#________________my edits___________________________________________________
def get_coordinates(coord_list, latvar, lonvar):
    "this takes coordinates from a .csv and assigns them to variables"

    end_row = len(coord_list)

    lon_ind=1
    lat_ind=2

    for row in range(0, end_row-1):#end_row - 1 due to the 0 index
        turbine_lat = coord_list[row][lat_ind]
        turbine_lon = coord_list[row][lon_ind]
        iy, ix = tunnel_fast(latvar, lonvar, turbine_lat, turbine_lon)
        print('Closest lat lon:', latvar[iy, ix], lonvar[iy, ix])

#________________________________________________________________________________________________________________________
ncfile = netCDF4.Dataset('NOGAPS_wind_level2_1.nc', 'r')
latvar = ncfile.variables['latitude']
lonvar = ncfile.variables['longitude']

#____added in to pass to get coordinates function
with open('Turbine_locs_no_header.csv','rb') as f:
    reader = csv.reader(f)
    coord_list = list(reader)
#_________take latitude from coordinateas function

get_coordinates(coord_list, latvar, lonvar)

#iy,ix = tunnel_fast(latvar, lonvar, turbine_lat, turbine_lon)#get these from the 'assign_coordinates_fromlist.py
#print('Closest lat lon:', latvar[iy,ix], lonvar[iy,ix])

SARwind = ncfile.variables['sar_wind'][:,:]
ModelWind = ncfile.variables['model_speed'][:,:]

print 'iy,ix' #appears to be the index of the value of Lat,lon
print SARwind[iy,ix]


ncfile.close()

当我尝试转换时

您可以使用 *args 解压缩参数列表(参见 the docs)。在你的情况下你可以做 tunnel_fast(latvar, lonvar, *coord_list[row])。您需要确保 coord_list[row] 中参数的顺序是正确的,如果 coord_list[row] 包含的值多于这两个值,那么您需要对其进行适当的切片。

感谢 a_guest

的帮助

lat0lon0 被传递为一个简单的问题 当需要 <type 'float'> 时,<type 'str'>tunnel_fast。这似乎来自将 coord_list 作为列表加载。

with open('Turbine_locs_no_header.csv','rb') as f:
    reader = csv.reader(f)
    coord_list = list(reader)

我使用的解决方法是将 lat0lon0 转换为 tunnel_fast

开头的浮点数
lat0 = float(lat0) 
lon0 = float(lon0)

我相信有一种更优雅的方法可以做到这一点,但它确实有效。