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

时间:2017-01-04 13:36:19

标签: python list csv coordinates netcdf

我正在使用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()

当我尝试转换

2 个答案:

答案 0 :(得分:1)

您可以使用*args解包参数列表(请参阅the docs)。在您的情况下,您可以tunnel_fast(latvar, lonvar, *coord_list[row])。您需要确保coord_list[row]中参数的顺序正确,如果coord_list[row]包含的值超过这两个值,则需要对其进行适当的切片。

答案 1 :(得分:0)

感谢a_guest的帮助

这是lat0lon0被传递的简单问题 需要<type 'str'>tunnel_fast<type 'float'>。这似乎来自加载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)

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