[SciPy-User] Populating a recarray from 0 size

Benjamin Root ben.root at ou.edu
Sun Aug 22 15:13:36 EDT 2010


On Sun, Aug 22, 2010 at 1:46 PM, Joe Kington <jkington at wisc.edu> wrote:

>
>
> On Sun, Aug 22, 2010 at 12:44 PM, Benjamin Root <ben.root at ou.edu> wrote:
>
>> On Sat, Aug 21, 2010 at 8:18 PM, Sergi Pons Freixes <spons at utm.csic.es>wrote:
>>
>>> Hi everybody,
>>>
>>> I'm interested in populating a recarray a row at a time. I thought in
>>> using:
>>>
>>> -------
>>> # Creation of empty recarray
>>> names = ["cruise", "SEQ", "param", "r2", "stderr", "slope", "intercept"
>>> formats = ["i4", "i4", "S10", "f4", "f4", "f4", "f4"]
>>> statsc = scipy.empty(0, dtype={"names":names, "formats":formats})
>>>
>>> # Adding row and setting values
>>> statsc = scipy.resize(statsc, statsc.size + 1)
>>> statsc["cruise"][-1] = cr
>>> statsc["SEQ"][-1] = ca
>>> statsc["param"][-1] = yvar
>>> ...
>>> -------
>>>
>>> But scipy.resize complains with:
>>> statsc = scipy.resize(statsc, statsc.size + 1)
>>>  File "/usr/lib/python2.6/site-packages/numpy/core/fromnumeric.py",
>>> line 833, in resize
>>>    if not Na: return mu.zeros(new_shape, a.dtype.char)
>>> ValueError: Empty data-type
>>>
>>> So, is scipy not happy because statsc.size is 0 on the first resize?
>>> In this case, how could I overcome this limitation?
>>>
>>> Regards,
>>> Sergi
>>>
>>>
>> Sergi,
>>
>> I had a similar need recently.  I was populating recarrays where I didn't
>> know the final size beforehand.  The way I solved the problem was to create
>> an iterator function and use .fromiter() to build the array.
>>
>> A simplified example:
>>
>> import numpy
>>
>> class foobar(object) :
>>     def __init__(self) :
>>        self._myval = 0
>>
>>     def __iter__(self) :
>>         return self
>>
>>     def next(self) :
>>         if self._myval >= 7 :
>>             raise StopIteration
>>
>>         self._myval += 1
>>         return self._myval
>>
>> gen = foobar()
>> a = numpy.fromiter(gen, dtype=[('Column', 'i4')])
>> print a
>>
>>
>> However... for some reason, I can't seem to get this working.  Maybe
>> someone else can spot my error?
>>
>
> I think the iterator needs to return a tuple, rather than a "bare" int.  At
> any rate, if you change "return self._myval" to "return (self._myval,)",
> things work perfectly.
>

Ah, right!

An even easier example would be:

def foobar(start, end) :
    curVal = start
    while curVal < end :
        yield (curVal,)
        curVal += 1

gen = foo(1, 10)
a = numpy.fromiter(gen, [('Column', 'i4')])
print a['Column']

Which woulld output:

[1 2 3 4 5 6 7 8 9]

I hope that helps!
Ben Root
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.scipy.org/pipermail/scipy-user/attachments/20100822/08982e79/attachment.html>


More information about the SciPy-User mailing list