RE: [Numpy-discussion] Accessing rank-0 array value?
![](https://secure.gravatar.com/avatar/7dd64dbe40f809b9f8276bde56c872fd.jpg?s=120&d=mm&r=g)
b has a scalar properties:
b+3 5
b.rank 0
The odd issue is that rank>0 arrays keeps their type in similar operations:
a = array((2,), type=Int16) a array([2], type=Int16)
a + 3 array([5], type=Int16)
I would expect that rank 0 arrays would behave like scalars with a given numarray type (Int8, UInt64, ...). Nadav. -----Original Message----- From: Peter Verveer [mailto:verveer@embl-heidelberg.de] Sent: Mon 07-Jun-04 12:27 To: Francesc Alted Cc: Numpy Discussion List Subject: Re: [Numpy-discussion] Accessing rank-0 array value? For instance:
float(b) 2.0
or probably more appropriate since it retains the type:
b[()] 2
Both not very intuitive, are there any better ways? On 7 Jun 2004, at 11:17, Francesc Alted wrote:
Hi,
Perhaps this is a stupid question, but I did not found any easy way to get the python object value from a rank-0 numarray array. That is:
from numarray import * b=array(2) b array(2) b[0] Traceback (most recent call last): File "<stdin>", line 1, in ? IndexError: Too many indices
In C, that seem to be possible provided you use the call: PyObject* PyArray_Return(PyArrayObject *apr)
Is there any way to do that in python?
------------------------------------------------------- This SF.Net email is sponsored by the new InstallShield X.
From Windows to Linux, servers to mobile, InstallShield X is the one installation-authoring solution that does it all. Learn more and evaluate today! http://www.installshield.com/Dev2Dev/0504
Numpy-discussion mailing list Numpy-discussion@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/numpy-discussion
![](https://secure.gravatar.com/avatar/faf9400121dca9940496a7473b1d8179.jpg?s=120&d=mm&r=g)
On Mon, 2004-06-07 at 06:50, Nadav Horesh wrote:
b has a scalar properties:
b+3 5
b.rank 0
The odd issue is that rank>0 arrays keeps their type in similar operations:
a = array((2,), type=Int16) a array([2], type=Int16)
a + 3 array([5], type=Int16)
I would expect that rank 0 arrays would behave like scalars with a given numarray type (Int8, UInt64, ...).
Nadav.
Originally, I think your expected behavior was the behavior. The official policy now, always subject to debate, is that rank-0 arrays should be a mostly hidden implementation detail. The fact that a scalar is returned here is a matter of consistency and no accident. (This is not to say that I'm confident that we're completely consistent... I'm just trying to explain the direction we're heading.) Todd -- Todd Miller <jmiller@stsci.edu>
![](https://secure.gravatar.com/avatar/b24e93182e89a519546baa7bafe054ed.jpg?s=120&d=mm&r=g)
Todd, What are the objections to returning a scalar? To me, this seems to be simpler than some kluge, such as float(array) or int(array). To use these, one has first to determine what array._type is. Colin W. Todd Miller wrote:
On Mon, 2004-06-07 at 06:50, Nadav Horesh wrote:
b has a scalar properties:
b+3
5
b.rank
0
The odd issue is that rank>0 arrays keeps their type in similar operations:
a = array((2,), type=Int16) a
array([2], type=Int16)
a + 3
array([5], type=Int16)
I would expect that rank 0 arrays would behave like scalars with a given numarray type (Int8, UInt64, ...).
Nadav.
Originally, I think your expected behavior was the behavior. The official policy now, always subject to debate, is that rank-0 arrays should be a mostly hidden implementation detail. The fact that a scalar is returned here is a matter of consistency and no accident. (This is not to say that I'm confident that we're completely consistent... I'm just trying to explain the direction we're heading.)
Todd
![](https://secure.gravatar.com/avatar/faf9400121dca9940496a7473b1d8179.jpg?s=120&d=mm&r=g)
On Mon, 2004-06-07 at 11:51, Colin J. Williams wrote:
Todd,
What are the objections to returning a scalar?
Where?
To me, this seems to be simpler than some kluge, such as float(array) or int(array). To use these, one has first to determine what array._type is.
I don't think so. What you get is driven by what you ask for, not the type of the array:
a = numarray.array(10) float(a) 10.0 int(a) 10 a = numarray.array(10.0) int(a) 10 float(a) 10.0 complex(a) (10+0j)
Regards, Todd
Colin W.
Todd Miller wrote:
On Mon, 2004-06-07 at 06:50, Nadav Horesh wrote:
b has a scalar properties:
b+3
5
b.rank
0
The odd issue is that rank>0 arrays keeps their type in similar operations:
a = array((2,), type=Int16) a
array([2], type=Int16)
a + 3
array([5], type=Int16)
I would expect that rank 0 arrays would behave like scalars with a given numarray type (Int8, UInt64, ...).
Nadav.
Originally, I think your expected behavior was the behavior. The official policy now, always subject to debate, is that rank-0 arrays should be a mostly hidden implementation detail. The fact that a scalar is returned here is a matter of consistency and no accident. (This is not to say that I'm confident that we're completely consistent... I'm just trying to explain the direction we're heading.)
Todd
-- Todd Miller <jmiller@stsci.edu>
![](https://secure.gravatar.com/avatar/81b3970c8247b2521d2f814de5b24475.jpg?s=120&d=mm&r=g)
First of all, thanks to everybody for their responses. For me, the basic problem is that a[()] notation would be the best way to get the python object with a type close to that of the numarray object. Why not letting a[...] or a[:] to return the same object as a[()]?. I know that this is not consistent with the "..." or ":" use in non-scalar arrays, but I find any of last two far more intuitive than a "()" index. Besides, IMHO, an scalar array is not a "regular" array, so the consistency restrictions should not be set as hard as they are now. Regards, -- Francesc Alted
![](https://secure.gravatar.com/avatar/ba366a43ea0322ddb4cf2462f8ad2596.jpg?s=120&d=mm&r=g)
I do not agree. The a[()] notation is consistent and clear if you know that you can index with a tuple of indices: you index a rank-0 array with a tuple of length zero. The "..." and ":" should do the same as for any other array: return the whole thing, not a single element. On 7 Jun 2004, at 18:27, Francesc Alted wrote:
First of all, thanks to everybody for their responses.
For me, the basic problem is that a[()] notation would be the best way to get the python object with a type close to that of the numarray object. Why not letting a[...] or a[:] to return the same object as a[()]?. I know that this is not consistent with the "..." or ":" use in non-scalar arrays, but I find any of last two far more intuitive than a "()" index.
Besides, IMHO, an scalar array is not a "regular" array, so the consistency restrictions should not be set as hard as they are now.
Regards,
-- Francesc Alted
------------------------------------------------------- This SF.Net email is sponsored by: GNOME Foundation Hackers Unite! GUADEC: The world's #1 Open Source Desktop Event. GNOME Users and Developers European Conference, 28-30th June in Norway http://2004/guadec.org _______________________________________________ Numpy-discussion mailing list Numpy-discussion@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/numpy-discussion
![](https://secure.gravatar.com/avatar/c7976f03fcae7e1199d28d1c20e34647.jpg?s=120&d=mm&r=g)
Peter Verveer wrote:
I do not agree. The a[()] notation is consistent and clear if you know that you can index with a tuple of indices: you index a rank-0 array with a tuple of length zero.
The "..." and ":" should do the same as for any other array: return the whole thing, not a single element.
Peter gets at the crux of the reasons behind the current behavior. (Much of this was discussed some time ago). There is a distinction between a scalar and a rank-0 array in that one expects that all the array semantics will be consistent with all other arrays. Thus "..." and ":" behave exactly the same. That discussion was centered on whether single element indexing should return rank-0 arrays or scalars. We chose scalars as more intuitive (and for performance reasons as well). There was hope that rank-0 arrays would be more convenient to use, and that they could also be indexed as a[0], however this is inconsistent with the shape as Peter points out (and as others before did as well). That being said, I'd like to understand why you (Francesc) would like to use rank-0 arrays. There is certainly a legitimate problem to be solved, and perhaps there are better alternatives. The original source of the previous rank-0 discussion was that they aided what had been dubbed "generic programming". This was being promoted primarily by the scipy guys and the general idea was to make it easier to write code that did not constantly have to check whether an input was scalar or an array. With scalars always mapping to rank-0 arrays, it was felt that this would aid writing code that would work for both scalars and arrays without any conditional tests. It's a good thing to want. I wonder if we should now develop tools to make writing such code much easier. Matlab apparently treats all scalars as rank-0 values and thus makes it fairly easy to deal with such things. On the other hand, Python does have real scalars so things are not quite so simple. One can wrap all inputs with array(), but then what will be returned will also be an array (rank-0 or whatever). That isn't always what is desired when scalars are given as an argument to a function. So if your needs are along this line, this seems like a good time to try to figure out ways of dealing with such issues. Perry
![](https://secure.gravatar.com/avatar/81b3970c8247b2521d2f814de5b24475.jpg?s=120&d=mm&r=g)
A Dilluns 07 Juny 2004 19:35, Perry Greenfield va escriure:
That discussion was centered on whether single element indexing should return rank-0 arrays or scalars. We chose scalars as more intuitive (and for performance reasons as well). There was hope that rank-0 arrays would be more convenient to use, and that they could also be indexed as a[0], however this is inconsistent with the shape as Peter points out (and as others before did as well).
That being said, I'd like to understand why you (Francesc) would like to use rank-0 arrays. There is certainly a legitimate problem to be solved, and perhaps there are better alternatives.
Well, I've come to use rank-0 arrays in a natural way in my libraries, and I liked to retrieve their content before returning it to the user. I was simply a bit surprised that retrieving that value was so hidden in documentation (in case that issue is documented at all, because I have not found it yet). My natural try was first to use "[0]" notation, and the error lost me. Suggestion: it would be possible to change the default error:
a[0] Traceback (most recent call last): File "<stdin>", line 1, in ? IndexError: Too many indices
by something like:
a[0] Traceback (most recent call last): File "<stdin>", line 1, in ? IndexError: rank-0 arrays don't accept integer indices. Use '()' (empty tuple) instead.
In order to provide an universal accessor to numarray objects, what about adding a .toscalar() (or .toobject()) method to them? That would return a python object whether you are using rank-0 arrays, regular arrays, CharArrays or RecArrays. That object would be the minimal python container that would keep the values inside these objects. In case of rank-0 arrays it would return a Bool, Int, Float or Complex. For a regular array, a list (perhaps a tuple?). For CharArrays, a list (tuple?) of strings. And for RecArrays a list (tuple) of tuples. Incidentally, I've noted an inconsistency in the .tostring behaviour:
a=array(126) a.tostring() ''
while I would expect a return value like:
chr(126) '~'
The original source of the previous rank-0 discussion was that they aided what had been dubbed "generic programming". This was being promoted primarily by the scipy guys and the general idea was to make it easier to write code that did not constantly have to check whether an input was scalar or an array. With scalars always mapping to rank-0 arrays, it was felt that this would aid writing code that would work for both scalars and arrays without any conditional tests. It's a good thing to want. I wonder if we should now develop tools to make writing such code much easier.
So if your needs are along this line, this seems like a good time to try to figure out ways of dealing with such issues.
My needs are restricted to very few lines of code, so I can pass by using the conditionals. However, yeah, I would be happy as well if I would be able to implement that kind of "generic programming". I find that to be elegant, although it may perfectly not worth the effort, I don't know. Well, for me the whole issue was getting rank-0 values as python objects. Sorry if my point of view is adding confusion to these issues. Cheers, -- Francesc Alted
![](https://secure.gravatar.com/avatar/55f7acf47233a7a98f5eb9dfd0b2d763.jpg?s=120&d=mm&r=g)
[SNIP]
a[0]
Traceback (most recent call last): File "<stdin>", line 1, in ? IndexError: Too many indices
by something like:
a[0]
Traceback (most recent call last): File "<stdin>", line 1, in ? IndexError: rank-0 arrays don't accept integer indices. Use '()' (empty tuple) instead.
This seems like a sensible idea. One might further restrict this and only raise it when a rank-0 array is indexed with zero, which is the only real case that causes confusion. In that case, I suggest the error message similar to: IndexError: Too many indices (Use A[()] to get scalar from rank-0 array A)
In order to provide an universal accessor to numarray objects, what about adding a .toscalar() (or .toobject()) method to them? That would return a python object whether you are using rank-0 arrays, regular arrays, CharArrays or RecArrays. That object would be the minimal python container that would keep the values inside these objects. In case of rank-0 arrays it would return a Bool, Int, Float or Complex. For a regular array, a list (perhaps a tuple?). For CharArrays, a list (tuple?) of strings. And for RecArrays a list (tuple) of tuples.
That's an interesting idea. `tolist` doesn't work on rank-0 arrays, sensibly enough. I would expect something called toscalar to only work on rank-0 arrays. I don't like that since I would like to see fewer special cases for rank-0 arrays not less. However, something called `toobject` (or `topyobject`, `tocoreobject`, etc) could return a core python object that was equivalent to the original array, which I believe is what you describe above. For example, after: obj = anArray.toobject() type = anArray.type() newArray = numarray.array(obj, type) `newArray` would always be equal to `anArray` in both value and type. The implementation of toobject could be as simple as: def toobject(self): if self.rank == 0: return self[()] else: return self.tolist() I'm not entirely convinced it's a good idea yet; I'd have to see some use cases, but it's an interesting idea in any event.
Incidentally, I've noted an inconsistency in the .tostring behaviour:
a=array(126) a.tostring()
''
Interesting. That's better than the memory error I get with Numarray-0.8. Or the indefinite hang I get with numarray 0.9.
while I would expect a return value like:
chr(126)
'~'
I think it should actually be returning the same things as array([126]).tostring(). That is: '\x80\x00\x00\x00' [SNIP] Regards, -tim
![](https://secure.gravatar.com/avatar/793e97a796dbd44a1d49522cbbe79556.jpg?s=120&d=mm&r=g)
Francesc Alted wrote:
For me, the basic problem is that a[()] notation would be the best way to get the python object with a type close to that of the numarray object. Why not letting a[...] or a[:] to return the same object as a[()]?. I know that this is not consistent with the "..." or ":" use in non-scalar arrays, but I find any of last two far more intuitive than a "()" index.
I don't agree with this idea as written; I think that a[:] should always return a. However, I think that there is another relevant point here: single-element arrays have no rank! In other words, from a purely mathematical point of view, it makes sense not to distinguish between the number 5, the vector with a single element 5, the 1x1 matrix 5, the 1x1x1 object-of-some-sort 5, etc. Accordingly, if a is a single-element array, it would be sensible for a[()]==a[0]==a[0,0]==a[0,0,0]==a[(0)]==a[(0, 0, 0, 0, 0)] Asking for the array's dimensions would then require a convention. -long-time-reader, first-time-poster Ben Schwartz
participants (8)
-
Benjamin M. Schwartz
-
Colin J. Williams
-
Francesc Alted
-
Nadav Horesh
-
Perry Greenfield
-
Peter Verveer
-
Tim Hochberg
-
Todd Miller