IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
4.5 Operating on Arrays


4.5 Operating on Arrays


4.5.1 Simple operations

If you have a keen eye, you have noticed that some of the previous examples did something new: they added a number to an array. Indeed, most Python operations applicable to numbers are directly applicable to arrays:

>>> print a
[1 2 3]
>>> print a * 3
[3 6 9]
>>> print a + 3
[4 5 6]
Note that the mathematical operators behave differently depending on the types of their operands. When one of the operands is an array and the other a number, the number is added to all the elements of the array, and the resulting array is returned. This is called broadcasting. This also occurs for unary mathematical operations such as sine and the negative sign:
>>> print sin(a)
[ 0.84147096 0.90929741 0.14112 ]
>>> print -a
[-1 -2 -3]
When both elements are arrays of the same shape, then a new array is created, where each element is the operation result of the corresponding elements in the original arrays:
>>> print a + a
[2 4 6]
If the operands of operations such as addition, are arrays having the same rank but different dimensions, then an exception is generated:
>>> a = array([1,2,3])
>>> b = array([4,5,6,7])                # note this has four elements
>>> print a + b
Traceback (innermost last):
  File "<stdin>", line 1, in ?
ValueError: Arrays have incompatible shapes
This is because there is no reasonable way for numarray to interpret addition of a (3,) shaped array and a (4,) shaped array.

Note what happens when adding arrays with different rank:

>>> print a
[1 2 3]
>>> print b
[[ 4  8 12]
 [ 5  9 13]
 [ 6 10 14]
 [ 7 11 15]]
>>> print a + b
[[ 5 10 15]
 [ 6 11 16]
 [ 7 12 17]
 [ 8 13 18]]
This is another form of broadcasting. To understand this, one needs to look carefully at the shapes of a and b:
>>> a.getshape()
(3,)
>>> b.getshape()
(4,3)
Note that the last axis of a is the same length as that of b (i.e. compare the last elements in their shape tuples). Because a's and b's last dimensions both have length 3, those two dimensions were ``matched'', and a new dimension was created and automatically ``assumed'' for array a. The data already in a were ``replicated'' as many times as needed (4, in this case) to make the shapes of the two operand arrays conform. This replication (broadcasting) occurs when arrays are operands to binary operations and their shapes differ, based on the following algorithm:
  • starting from the last axis, the axis lengths (dimensions) of the operands are compared,
  • if both arrays have axis lengths greater than 1, but the lengths differ, an exception is raised,
  • if one array has an axis length greater than 1, then the other array's axis is ``stretched'' to match the length of the first axis; if the other array's axis is not present (i.e., if the other array has smaller rank), then a new axis of the same length is created.

Operands with the following shapes will work:

(3, 2, 4) and (3, 2, 4)
(3, 2, 4) and (2, 4)
(3, 2, 4) and (4,)
(2, 1, 2) and (2, 2)

But not these:

(3, 2, 4) and (2, 3, 4)
(3, 2, 4) and (3, 4)
(4,) and (0,)
(2, 1, 2) and (0, 2)

This algorithm is complex to describe, but intuitive in practice.


4.5.2 In-place operations

Beginning with Python 2.0, Python supports the in-place operators +=, -=, *=, and /=. Numarray supports these operations, but you need to be careful. The right-hand side should be of the same type. Some violation of this is possible, but in general contortions may be necessary for using the smaller ``kinds'' of types.

>>> x = array ([1, 2, 3], type=Int16)
>>> x += 3.5
>>> print x
[4 5 6]

Send comments to the NumArray community.