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

Hanlie Pretorius hanlie.pretorius at gmail.com
Thu Oct 14 13:22:46 CEST 2010


Ok, now I see what I did. Legacy from when the get_rain_data function
returned precipitation and error. I forgot to remove the brackets from
the 'return [precip]' statement.

It works perfectly now. Thanks for all the help.

2010/10/14, Evert Rol <evert.rol at gmail.com>:
>> 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