NOTICE: This version of the NSF Unidata web site (archive.unidata.ucar.edu) is no longer being updated.
Current content can be found at unidata.ucar.edu.
To learn about what's going on, see About the Archive Site.
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
netcdfgroup
archives: