Re: [netcdfgroup] Read NETCDF using Java library (now Python)

  • To: Chris Barker <chris.barker@xxxxxxxx>
  • Subject: Re: [netcdfgroup] Read NETCDF using Java library (now Python)
  • From: "Signell, Richard" <rsignell@xxxxxxxx>
  • Date: Mon, 9 Feb 2015 13:22:17 -0500
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



  • 2015 messages navigation, sorted by:
    1. Thread
    2. Subject
    3. Author
    4. Date
    5. ↑ Table Of Contents
  • Search the netcdfgroup archives: