2017-01-04 10 views
0

Я использую код из workshop для извлечения данных из файлов netCDF по координатам, ближайшим к моим указанным координатам. При использовании только один набор координат я могу извлечь значения, мне нужно без проблем, как показано ниже:Python: передача координат из списка в функцию

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_lat и turbine_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() 

Когда я пытаюсь преобразовать

+0

Можете ли вы обновить форматирование кода в своем первом примере кода, пожалуйста. Я бы хотел, но его не было 6 символов. –

+0

@EmettSpeer. Я исправил отступы в первом разделе, что еще нужно сортировать? –

+0

Я только заметил одну проблему форматирования. –

ответ

0

Благодаря помощи a_guest

Это была простая проблема lat0 и lon0 передается в <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) 

Обходной я использовал для преобразования lat0 и lon0 к поплавки в начале tunnel_fast

lat0 = float(lat0) 
lon0 = float(lon0) 

Я уверен, что есть более элегантный способ сделать это, но это работает.

1

Вы можете распаковать список аргументов, используя *args (см the docs). В вашем случае вы можете сделать tunnel_fast(latvar, lonvar, *coord_list[row]). Вы должны убедиться, что порядок аргументов в coord_list[row] верен, и если coord_list[row] содержит больше двух значений, вам необходимо отрезать его соответствующим образом.

+0

Спасибо, ошибка трассировки такая же, как и выше, с iy, ix = tunnel_fast (latvar, lonvar, * coord_list [row]) 'вместо' iy, ix = tunnel_fast (latvar, lonvar, turbine_lat, turbine_lon) ' –

+1

Проблема в том, что 'lat0' (например) имеет тип' list' и, следовательно, не поддерживает умножение на 'float' (хотя умножение на' int', вероятно, не то, что вы хотите!). Проверьте 'print type (lat0)' и 'print lat0' в начале' tunnel_fast', и вы увидите. Вы как-то передаете неправильные аргументы. –

+0

Да, вы правы.в рабочей версии кода это '' и '' в нерабочей версии. –