I encouraged Jules A to post this to stackoverflow and tag with
"netcdf" and "python". I have the answer, but prefer to post it
there because:
1) someone in the community may have a better solution, and if so
their answer will float to the top
2) code snippets become very confused in e-mail threads
3) I want more stackoverflow points.
-Rich
On Mon, Feb 9, 2015 at 1:05 PM, Chris Barker <chris.barker@xxxxxxxx> wrote:
> Do you have a (hopefully small) sample netcdf file to share? That makes it a
> lot easier to debug.
>
> Also -- I can't help myself, so here are suggestions for making your code
> more "pythonic":
>
>
>> from netCDF4 import Dataset;
>>
>> from netCDF4 import num2date;
>
>
> no need for semi-colons! also, no biggie, but you can do:
>
> from netCDF4 import Dataset, num2date
>
>>
>> filename = "C:/filename.nc"
>>
>> nc = Dataset(filename, 'r', Format='NETCDF4')
>> print nc.variables
>
>
>>
>> print 'Variable List'
>>
>> for i in nc.variables:
>> print [i, nc.variables[i].units, nc.variables[i].shape]
>
>
> when you write a for loop like this, "i" gets assigned to the variable
> objects, so you should be able to just do:
>
> for var in nc.variables:
> print var, var.units, var.shape
>
>
>>
>> # get coordinates variables
>>
>> lats = nc.variables['latitude'][:]
>> lons = nc.variables['longitude'][:]
>>
>> try:
>>
>> assert(nc.variables['latitude'].units == 'degrees_north')
>> except:
>> raise AttributeError('latitude units attribute not what was expected'
>
>
> using an assert and caching it is odd, either simply:
>
> assert nc.variables['latitude'].units == 'degrees_north'
>
> or maybe:
>
> if nc.variables['latitude'].units != 'degrees_north':
> raise AttributeError('latitude units attribute not what was expected'
>
>>
>> sfc= nc.variables['Min_SFC'][:]
>>
>> times = nc.variables['time'][:]
>>
>>
>> # convert time
>>
>> print "Converting Dates"
>> units = nc.variables['time'].units
>> dates = num2date (times[:], units=units, calendar='365_day')
>>
>> #print [dates.strftime('%Y%m%d%H') for date in dates]
>>
>>
>> header = ['Latitude', 'Longitude']
>>
>>
>> # append dates to header string
>>
>> for d in dates:
>> print d
>> header.append(d)
>>
>> # write to file
>> import csv
>>
>> with open('Output.csv', 'wb') as csvFile:
>>
>> outputwriter = csv.writer(csvFile, delimiter=',')
>> outputwriter.writerow(header)
>> outputwriter.writerow(content)
>
>
> here is your bug:
>
> "with" is a context manager -- the idea is that is handles closing teh
> file, etc for you. It will do that when you leave the with block. In this
> case, you don't sem to ahve anything in the with block at all -- surprozed
> there isn't an error., but it should be indented after the with:
>
> with open('Output.csv', 'wb') as csvFile:
> outputwriter = csv.writer(csvFile, delimiter=',')
> outputwriter.writerow(header)
> outputwriter.writerow(content)
>
> when you fall off that indentation level the file will be closed.
>
> So you need ALL your writing code in that blcok, or you could not use with,
> and simply do:
>
> csvFile = open('Output.csv', 'wb')
> outputwriter = csv.writer(csvFile, delimiter=',')
> outputwriter.writerow(header)
> outputwriter.writerow(content)
>
> then close the file at the end of your script -- or do'nt bother, it will
> get closed fine when the script ends.
>
>> def WriteContent(outputwriter, content):
>>
>> outputwriter.writerow(content)
>>
>> return
>
>
> no sure what the point of this is, why not simple call:
>
> outputwriter.writerow(content)
>
> when you need it.
>
>> for l in lons:
>> content =[lats[l], lons[l]]
>> WriteContent(outputwriter, content)
>
>
> this looks wrng too -- "for l in lons" will assign the longitudes to l each
> time, not an index. IF you want to loop thorugh two sequences as once, you
> can use zip()
>
> for lat, lon in zip(lats, lons):
> outputwriter.writerow( [lat, lon] )
>
> though, in fact, this will probably work:
>
> for coords in zip(lats, lons):
> outputwriter.writerow(coords )
>
> or, if you want to get really fancy, use s list comprehension:
>
> [outputwriter.writerow(coords) for coords in zip (lats, lons) ]
>
> HTH,
>
> -Chris
>
>
> --
>
> Christopher Barker, Ph.D.
> Oceanographer
>
> Emergency Response Division
> NOAA/NOS/OR&R (206) 526-6959 voice
> 7600 Sand Point Way NE (206) 526-6329 fax
> Seattle, WA 98115 (206) 526-6317 main reception
>
> Chris.Barker@xxxxxxxx
>
> _______________________________________________
> netcdfgroup mailing list
> netcdfgroup@xxxxxxxxxxxxxxxx
> For list information or to unsubscribe, visit:
> http://www.unidata.ucar.edu/mailing_lists/
--
Dr. Richard P. Signell (508) 457-2229
USGS, 384 Woods Hole Rd.
Woods Hole, MA 02543-1598