bug in object arrays:
a = array([1,2]) b = array([3,4]) c = objects.array([a,b]) Traceback (most recent call last): File "<stdin>", line 1, in ? File "/System/Library/Frameworks/Python.framework/Versions/2.3/lib/
Is this a bug? This should result in an array of numpy arrays, but it does give an error: python2.3/site-packages/numarray/objects.py", line 732, in array return fromlist(sequence, shape) File "/System/Library/Frameworks/Python.framework/Versions/2.3/lib/ python2.3/site-packages/numarray/objects.py", line 755, in fromlist return ObjectArray(objects=l, shape=shape) File "/System/Library/Frameworks/Python.framework/Versions/2.3/lib/ python2.3/site-packages/numarray/objects.py", line 506, in __init__ oshape = _shapeFromNestedSequence(objects) File "/System/Library/Frameworks/Python.framework/Versions/2.3/lib/ python2.3/site-packages/numarray/objects.py", line 289, in _shapeFromNestedSequence return [len(s)] + _shapeFromNestedSequence(s[0]) TypeError: can only concatenate list (not "tuple") to list
On Sun, 2004-06-06 at 12:10, Peter Verveer wrote:
Is this a bug?
I think this is more of a bonanza: a bug and an ambiguity.
This should result in an array of numpy arrays, but it does give an error:
a = array([1,2]) b = array([3,4]) c = objects.array([a,b]) Traceback (most recent call last): File "<stdin>", line 1, in ? File "/System/Library/Frameworks/Python.framework/Versions/2.3/lib/ python2.3/site-packages/numarray/objects.py", line 732, in array return fromlist(sequence, shape) File "/System/Library/Frameworks/Python.framework/Versions/2.3/lib/ python2.3/site-packages/numarray/objects.py", line 755, in fromlist return ObjectArray(objects=l, shape=shape) File "/System/Library/Frameworks/Python.framework/Versions/2.3/lib/ python2.3/site-packages/numarray/objects.py", line 506, in __init__ oshape = _shapeFromNestedSequence(objects) File "/System/Library/Frameworks/Python.framework/Versions/2.3/lib/ python2.3/site-packages/numarray/objects.py", line 289, in _shapeFromNestedSequence return [len(s)] + _shapeFromNestedSequence(s[0]) TypeError: can only concatenate list (not "tuple") to list
The bug is that your example didn't work as follows:
import numarray.objects as obj obj.array([a,b]) ObjectArray([[1, 2], [3, 4]])
Returning a shape=(2,) object array is another obvious behavior but turns out not to be what Numeric does and hence not what numarray does either. Faced with sequence objects, Numeric and numarray both just keep recursing (logically anyway) until they hit something which isn't a sequence. Thus, they return not a 1D array of arrays, but a 2D array of numbers:
import Numeric Numeric.array([a,b], typecode='O') array([[1 , 2 ], [3 , 4 ]],'O')
With some new code I added today, numarray of the future will support your preferred behavior like this, barring further discussion:
obj.array([a,b], rank=1) ObjectArray([array([1, 2]), array([3, 4])])
Here, the new "rank" parameter explicitly specifies the expected rank of the resulting array, defining the point at which nested sequences become "objects in their own right". Perry's inclination was that rank should default to 1 so that your expected behavior was the default. Since that's not backward compatible with Numeric (or numarray-0.9) I think maybe rank=None is better. In this case, rank=None is equivalent to rank=2. How does the rank parameter sound? Regards, Todd
The bug is that your example didn't work as follows:
import numarray.objects as obj obj.array([a,b]) ObjectArray([[1, 2], [3, 4]])
Returning a shape=(2,) object array is another obvious behavior but turns out not to be what Numeric does and hence not what numarray does either. Faced with sequence objects, Numeric and numarray both just keep recursing (logically anyway) until they hit something which isn't a sequence. Thus, they return not a 1D array of arrays, but a 2D array of numbers:
import Numeric Numeric.array([a,b], typecode='O') array([[1 , 2 ], [3 , 4 ]],'O')
With some new code I added today, numarray of the future will support your preferred behavior like this, barring further discussion:
obj.array([a,b], rank=1) ObjectArray([array([1, 2]), array([3, 4])])
Here, the new "rank" parameter explicitly specifies the expected rank of the resulting array, defining the point at which nested sequences become "objects in their own right". Perry's inclination was that rank should default to 1 so that your expected behavior was the default. Since that's not backward compatible with Numeric (or numarray-0.9) I think maybe rank=None is better. In this case, rank=None is equivalent to rank=2.
How does the rank parameter sound?
Regards, Todd
I see the logic of the recursing but it was unexpected in this particular example. The rank parameter is a solution, but I don't think it is very elegant to be honest. rank=1 should certainly not be the default, because it would not work if the rank of the desired object array is not one... For example, I want to make object arrays of arbitrary rank containing numarrays, so I would need to specify the rank anyway. How about stopping the recursion as soon as an object is found that is not a sequence, or that is a sequence of but of a different type? In my example the outer sequence is a list and the objects are arrays, so as soon as a array is seen the recursion would stop, giving the desired behavior. Is this idea too complex? If not, could some optional argument switch to this behaviour? Or maybe some special value for rank (-1) could be used for that? The rank parameter would still be useful if you want to stop the recursion in a nested list, then you must give some kind of hint anyway. It would give the desired behavior in many cases, so I would actually prefer to see something like that as the default. Maybe my suggestion would not break things to much since nesting different types of sequence to generate a homogeneous object array may not be done often anyway (its not what you want usually, I guess). Cheers, Peter
participants (2)
-
Peter Verveer
-
Todd Miller