[Tutor] Writing elements of an array to a file using CSV module

Evert Rol evert.rol at gmail.com
Thu Oct 14 13:08:44 CEST 2010


> Thanks for the reply. I've tried your suggestion and am still getting
> an error (posted below code). Since my posting, I've also added the
> code to convert the numpy array to a list. My complete script is:
> 
> -----
> # -*- coding: utf-8 -*-
> 
> import pupynere
> import os
> import csv
> import glob
> 
> def get_file_details(filename):
>    sub1='3B42.'
>    sub2='.nc'
>    extract=filename.split(sub1)[-1].split(sub2)[0]
>    elements=extract.split('.')
>    ure={'0':'00:00:00',
>         '3':'03:00:00',
>         '6':'06:00:00',
>         '9':'09:00:00',
>         '12':'12:00:00',
>         '15':'15:00:00',
>         '18':'18:00:00',
>         '21':'21:00:00'}
>    date='20'+elements[0]
>    time=ure[elements[1]]
>    return[date,time]
> 
> def get_rain_data(filename):
>    # trmm blocks covering study area
>    rows=[87,86,85,86]
>    cols=[833,833,833,834]
> 
>    # open file
>    file = pupynere.netcdf_file(filename,'r')
>    # read data
>    precipitation=file.variables['precipitation']
>    # close file    file.close()
> 
>    # read values for blocks of interest
>    precip=precipitation[rows,cols]
>    # convert numpy array to list
>    precip=precip.tolist()
>    return[precip]

You just converted precip to a list (precip.tolist()), then, in the next line, you're turning that into a list.
So you get a list within a list, which results in the errors below. Exactly as you hinted at yourself below.

(In fact, if you now would do
>>> data[0]
[0.0, 0.0, 0.0, 0.0]
because this is the representation (repr). Not the 0.0 you previously showed.)

Once you get rid of the extra list, you can use either float(data[0]) and %f (if you require detailed formatting) or just simply %s, as Alan suggested.

  Evert



> 
> 
> # get list of .nc files in folder
> os.chdir('F:\\Hanlie\\UCT\\M.Sc\\Data\\TRMM\\2000\\02_Februarie')
> filepattern='*.nc'
> nc_files=glob.glob(filepattern)
> 
> # write to CSV-file with spaces as delimiter
> csv.register_dialect('spaces', delimiter=' ')
> outfilename="trmm_c83a_feb2000.txt"
> out_text=open(outfilename, 'wb')
> writer = csv.writer(out_text,dialect='spaces')
> 
> for file in nc_files:
>    file_details=get_file_details(file)
>    data=get_rain_data(file)
>    writer.writerow(('%s' % (file_details[0]),'%s' %
> (file_details[1]),'%f' % float(data[0])))
> 
> out_text.close()
> -----
> 
> I now get the error:
> -----
> Traceback (most recent call last):
>  File "F:\Hanlie\UCT\M.Sc\Data\TRMM\lees_netcdf_per_trmm_blok_skryf_vir_pcraster.py",
> line 76, in <module>
>    writer.writerow(('%s' % (file_details[0]),'%s' %
> (file_details[1]),'%f' % float(data[0])))
> TypeError: float() argument must be a string or a number
> -----
> 
> I tried the other suggestion on the list (posted by Alan Gould),
> namely to replace the %f formatting string with %s in the
> write.writerow statement:
> -----
> writer.writerow( ( file_details[0], file_details[1], str(data[0])  ) )
> -----
> 
> This produces a file with lines such as:
> -----
> 20000201 00:00:00 "[0.0, 0.0, 0.0, 0.0]"
> -----
> 
> I seem to have a list within a list, I'm not sure why. I could write
> the list elements to variables before I write to the file, but it
> doesn't seem like a very elegant solution.
> 
> Can anyone see why I have such a nested data structure? Or is the
> problem something completely different?
> 
> Thanks
> Hanlie
> 
> 
> 2010/10/14, Evert Rol <evert.rol at gmail.com>:
>>> I have a numpy array ('data') that is the result of reading a netCDF
>>> file, and it typically looks like this:
>>> 
>>> array([ 0.,  0.,  0.,  0.], dtype=float32)
>>> 
>>> 
>>> I want to write this, after a date and time, to a CSV file, so the CSV
>>> file would have the entry:
>>> 
>>>   2000-02-01,09:00,0.0,0.0,0.0,0.0
>>> 
>>> 
>>> The code I'm using to test it, is:
>>> 
>>> # file_details[0] is the date and file_details[1] is the time
>>> writer.writerow(('%s' % (file_details[0]),'%s' %
>>> (file_details[1]),'%f' % (data[0])))
>>> 
>>> 
>>> In my opinion, this should give an output line:
>>> 
>>> 2000-02-01,09:00,0.0
>>> 
>>> 
>>> Instead, I get an error
>>> 
>>> TypeError: float argument required, not numpy.ndarray
>>> 
>>> 
>>> 
>>> Can someone please explain to me why data[0] is giving a numpy array
>>> rather than one element? I don't understand it, since I get:
>>> 
>>>>>> data[0]
>>> 0.0
>> 
>> This means very little, since a string '0.0' will show the same output when
>> printed:
>>>>> print '0.0'
>> 0.0
>> 
>> The exception says 'TypeError', so try:
>> 
>>>>> type(data[0])
>> <type 'numpy.float32'>
>> 
>> Which is indeed what you specified at the start using dtype=float32.
>> 
>> The standard string formatting doesn't know what to do with a numpy.float32,
>> so you'll need to convert it to a float:
>> 
>>>>> '%f' % float(data[0])
>> '0.000000'
>> 
>> (use proper float formatting to get at '0.0', which is what you apparently
>> want.)
>> 
>> 
>>  Evert
>> 
>> 



More information about the Tutor mailing list