Hello, I recently discovered the following behavior when fetching values from a Numeric array. Can somebody offer some insight? #1) import Numeric a = Numeric.zeros((2, 2), 'i') n = a[1, 1] # fetch interesting value from array print n a[1, 1] = 10 # change array print n # blam print type(n) # huh [bash]$ python 1.py 0 10 <type 'array'> but #2) import Numeric a = Numeric.zeros((2,), 'i') n = a[1] print n a[1] = 10 print n print type(n) [bash]$ python 2.py 0 0 <type 'int'> #2 works the way one would expect, and #1 does not (n changes). They should at least both behave the same. :) At a minimum, naive use of arrays can lead to confusing or disastrous results, since a single value fetched from an array can change behind your back. It appears n is aliased into a, but preserves its value when a is deleted (with del(a)). What happens to the "rest of" a? I'm using Python 2.2, Numeric21.0, on both Unix and Win32. Thanks, Larry
On Tue, 28 May 2002, Larry Denneau wrote:
Hello,
I recently discovered the following behavior when fetching values from a Numeric array. Can somebody offer some insight?
#1)
import Numeric
a = Numeric.zeros((2, 2), 'i') n = a[1, 1] # fetch interesting value from array print n a[1, 1] = 10 # change array print n # blam print type(n) # huh
[bash]$ python 1.py 0 10 <type 'array'>
but
#2)
import Numeric
a = Numeric.zeros((2,), 'i') n = a[1] print n a[1] = 10 print n print type(n)
[bash]$ python 2.py 0 0 <type 'int'>
#2 works the way one would expect, and #1 does not (n changes). They should at least both behave the same. :) At a minimum, naive use of arrays can lead to confusing or disastrous results, since a single value fetched from an array can change behind your back.
Use a[1][1] = 10 and the output will be 0 0 <type 'int'> I find it is an useful feature in Numeric to have both behaviours of either using a[1,1] or a[1][1]. You may want to dig into Numeric's userguide to get a more detailed explanation of the differences. Regards, Pearu
Pearu Peterson said:
On Tue, 28 May 2002, Larry Denneau wrote:
Hello,
I recently discovered the following behavior when fetching values from a Numeric array. Can somebody offer some insight?
#1)
import Numeric
a = Numeric.zeros((2, 2), 'i') n = a[1, 1] # fetch interesting value from array print n a[1, 1] = 10 # change array print n # blam print type(n) # huh
[bash]$ python 1.py 0 10 <type 'array'>
[ deleted]
Use
a[1][1] = 10
and the output will be
0 0 <type 'int'>
I find it is an useful feature in Numeric to have both behaviours of either using a[1,1] or a[1][1]. You may want to dig into Numeric's userguide to get a more detailed explanation of the differences.
Regards, Pearu
Hi Pearu, I assume you mean n = a[1][1] which produces the expected behavior. All the Numpy documentation examples (see http://pfdubois.com/numpy/html2/numpy6.html#pgfId36033, "Getting and Stting Array Values") use the [x, y] notation instead of [x][y], so I would consider this a bug in the documentation, since the [x, y] method leads to unexpected behavior. I'm still curious what happens to the original array when n=a[1, 1] del(a) but that may have to wait until I have time to peruse the Numeric source. Thanks, Larry
Hi Larry, On Tue, 28 May 2002, Larry Denneau wrote:
All the Numpy documentation examples (see http://pfdubois.com/numpy/html2/numpy6.html#pgfId36033, "Getting and Stting Array Values") use the [x, y] notation instead of [x][y], so I would consider this a bug in the documentation, since the [x, y] method leads to unexpected behavior.
If you look the section "Slicing Arrays" then a[1] is actually a[1,:], that is, an one dimensional array. From your description, a[1,1] must be an array with 0 rank. It seems that the Numeric documentation is missing (though, I didn't look too hard) the following rules of thumb: If `a' is rank 1 array, then a[i] is Python scalar or object. [MISSING] If `a' is rank > 1 array, then a[i] is a subarray a[i,...]
I'm still curious what happens to the original array when
n=a[1, 1] del(a)
I think the original array `a' is not actually deleted until `n' gets deleted. If I recall correctly, then `n' is a subarray of `a' so that internally it contains only a reference to `a' in the sense that a.data==n.data but strides and dimension arrays differ. Pearu
Pearu Peterson <pearu@cens.ioc.ee> writes:
an array with 0 rank. It seems that the Numeric documentation is missing (though, I didn't look too hard) the following rules of thumb:
If `a' is rank 1 array, then a[i] is Python scalar or object. [MISSING]
Or rather:  If `a' is rank 1 array with elements of type Int, Float, or Complex, then a[i] is Python scalar or object. [MISSING]  If `a' is rank 1 array with elements of type Int16, Int32, Float32, or Complex32, then a[i] is a rank 0 array. [MISSING]  If `a' is rank > 1 array, then a[i] is a subarray a[i,...] The rank0 arrays are the #1 question topic for users of my netCDF interface (for portability reasons, netCDF integer arrays map to Int32, not Int, so scalar integers read from a netCDF array are always rank0 arrays), and almost everybody initially claims that it's a bug, so some education seems necessary. Konrad.   Konrad Hinsen  EMail: hinsen@cnrsorleans.fr Centre de Biophysique Moleculaire (CNRS)  Tel.: +332.38.25.56.24 Rue Charles Sadron  Fax: +332.38.63.15.17 45071 Orleans Cedex 2  Deutsch/Esperanto/English/ France  Nederlands/Francais 
 Original Message  From: "Konrad Hinsen" <hinsen@cnrsorleans.fr> To: "Pearu Peterson" <pearu@cens.ioc.ee> Cc: <numpydiscussion@lists.sourceforge.net> Sent: Wednesday, May 29, 2002 4:08 AM Subject: Re: [Numpydiscussion] Bug: extremely misleading array behavior
Pearu Peterson <pearu@cens.ioc.ee> writes:
an array with 0 rank. It seems that the Numeric documentation is missing (though, I didn't look too hard) the following rules of thumb:
If `a' is rank 1 array, then a[i] is Python scalar or object. [MISSING]
Or rather:
 If `a' is rank 1 array with elements of type Int, Float, or Complex, then a[i] is Python scalar or object. [MISSING]
 If `a' is rank 1 array with elements of type Int16, Int32, Float32, or Complex32, then a[i] is a rank 0 array. [MISSING]
 If `a' is rank > 1 array, then a[i] is a subarray a[i,...]
The rank0 arrays are the #1 question topic for users of my netCDF interface (for portability reasons, netCDF integer arrays map to Int32, not Int, so scalar integers read from a netCDF array are always rank0 arrays), and almost everybody initially claims that it's a bug, so some education seems necessary.
I don't think education is the answer here. We need to change Numeric to have uniform behavior across all typecodes. Having alternative behaviors for indexing based on the typecode can lead to very difficult to find bugs. Generic routines meant to work with any Numeric type can brake a year later when someone passes in an array with a seemingly compatible type. Also, because coersion can silently change typecodes during arithmetic operations, code written expecting one behavior can all the sudden exihibit the other. That is very dangerous and hard to test. eric
I don't think education is the answer here. We need to change Numeric to have uniform behavior across all typecodes.
I agree that this would be the better solution. But until this is done...
Having alternative behaviors for indexing based on the typecode can lead to very difficult to find bugs. Generic routines meant to work
The differences are not that important, in most circumstances rank0 arrays and scalars behave in the same way. The problems occur mostly with code that does explicit type checking. The best solution, in my opinion, is to provide scalar objects corresponding to lowprecision ints and floats, as part of NumPy. Konrad.   Konrad Hinsen  EMail: hinsen@cnrsorleans.fr Centre de Biophysique Moleculaire (CNRS)  Tel.: +332.38.25.56.24 Rue Charles Sadron  Fax: +332.38.63.15.17 45071 Orleans Cedex 2  Deutsch/Esperanto/English/ France  Nederlands/Francais 
Konrad said:
The best solution, in my opinion, is to provide scalar objects corresponding to lowprecision ints and floats, as part of NumPy.
Konrad.
One of the thoughts I had in mind for the "kinds" proposal was to support this. I was going to do the float32 object as part of it as a demo of how it would work. So I got out the float object from Python, figuring I would just change a few types et voila. Not. It is very hard to understand, and I don't even understand the reasons it is hard to understand. Perhaps a young person with a high tolerance for pain would look at this?
On Mon, 20020603 at 10:54, Paul F Dubois wrote:
Konrad said:
The best solution, in my opinion, is to provide scalar objects corresponding to lowprecision ints and floats, as part of NumPy.
Konrad.
This seems like a good idea. It's been an old source of confusion. On a related note, how does the community feel about retrofitting Numeric with unsigned shorts and unsigned ints. I've got the code to do it already written. Travis
Hey Larry, I actually thought, as you did, that indexing the array returns an element converted to a scalar  and it does in the "default" cases when you don't specify a nonstandard typecode. After testing, it looks like values that are representable as native Python types ('l', 'd', and 'D') are returned as actual values while nonstandard types are returned as views into the array. Is this intentional? It is dangerous to have the behavior change based on the type. It seems they should all be views or they should all be converted to a scalar. Here is your test code modified to test all Numeric types: import Numeric def test_index(typecode): print 'typcode:', typecode a = Numeric.zeros((2, 2), typecode) n = a[1, 1] # fetch interesting value from array print n a[1, 1] = 10 # change array print n # blam print type(n) # huh print print 'Numeric version:', Numeric.__version__ for t in ['i','1','s','l','f','d','F','D']: test_index(t) And here is the output. Look at the types returned. C:\home\ej\wrk\junk>python num_index.py Numeric version: 21.0 typcode: i 0 10 <type 'array'> typcode: 1 0 10 <type 'array'> typcode: s 0 10 <type 'array'> typcode: l 0 0 <type 'int'> typcode: f 0.0 10.0 <type 'array'> typcode: d 0.0 0.0 <type 'float'> typcode: F 0j (10+0j) <type 'array'> typcode: D 0j 0j <type 'complex'> eric  Original Message  From: "Larry Denneau" <larryd@pangalactic.com> To: <numpydiscussion@lists.sourceforge.net> Sent: Tuesday, May 28, 2002 1:13 PM Subject: [Numpydiscussion] Bug: extremely misleading array behavior
Hello,
I recently discovered the following behavior when fetching values from a Numeric array. Can somebody offer some insight?
#1)
import Numeric
a = Numeric.zeros((2, 2), 'i') n = a[1, 1] # fetch interesting value from array print n a[1, 1] = 10 # change array print n # blam print type(n) # huh
[bash]$ python 1.py 0 10 <type 'array'>
but
#2)
import Numeric
a = Numeric.zeros((2,), 'i') n = a[1] print n a[1] = 10 print n print type(n)
[bash]$ python 2.py 0 0 <type 'int'>
#2 works the way one would expect, and #1 does not (n changes). They should at least both behave the same. :) At a minimum, naive use of arrays can lead to confusing or disastrous results, since a single value fetched from an array can change behind your back.
It appears n is aliased into a, but preserves its value when a is deleted (with del(a)). What happens to the "rest of" a?
I'm using Python 2.2, Numeric21.0, on both Unix and Win32.
Thanks, Larry
_______________________________________________________________
Don't miss the 2002 Sprint PCS Application Developer's Conference August 2528 in Las Vegas  http://devcon.sprintpcs.com/adp/index.cfm
_______________________________________________ Numpydiscussion mailing list Numpydiscussion@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/numpydiscussion
participants (6)

eric

Konrad Hinsen

Larry Denneau

Paul F Dubois

Pearu Peterson

Travis Oliphant