NetCDF group,
Just posting back here in case folks are not familiar with
stackoverflow or are interested in possible solutions to the problem
asked:
http://stackoverflow.com/questions/28420988/how-to-read-netcdf-file-and-write-to-csv-using-python
On Mon, Feb 9, 2015 at 1:24 PM, Chris Barker <chris.barker@xxxxxxxx> wrote:
> On Mon, Feb 9, 2015 at 10:22 AM, Signell, Richard <rsignell@xxxxxxxx> wrote:
>>
>> I encouraged Jules A to post this to stackoverflow and tag with
>> "netcdf" and "python".
>
>
> good point -- that is a better forum for this kind of question.
>
>
>>
>> 3) I want more stackoverflow points.
>
>
> why didn't you say so? I'll go give you some upvotes ;-)
>
> -Chris
>
>
>
>>
>> -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
>
>
>
>
> --
>
> 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
--
Dr. Richard P. Signell (508) 457-2229
USGS, 384 Woods Hole Rd.
Woods Hole, MA 02543-1598