IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
4.2 Creating arrays from scratch


4.2 Creating arrays from scratch


4.2.1 array() and types

array( sequence=None, typecode=None, copy=1, savespace=0, type=None, shape=None)
There are many ways to create arrays. The most basic one is the use of the array function:
>>> a = array([1.2, 3.5, -1])
to make sure this worked, do:
>>> print a
[ 1.2  3.5 -1. ]
The array function takes several arguments -- the first one is the values, which can be a Python sequence object (such as a list or a tuple). If the optional argument type is omitted, numarray tries to find the best data type which can represent all the elements.

Since the elements we gave our example were two floats and one integer, it chose Float64 as the type of the resulting array. One can specify unequivocally the type of the elements -- this is especially useful when, for example, one wants an array contains floats even though all of its input elements are integers:

>>> x,y,z = 1,2,3
>>> a = array([x,y,z])                  # integers are enough for 1, 2 and 3
>>> print a
[1 2 3]
>>> a = array([x,y,z], type=Float32)    # not the default type
>>> print a
[ 1.  2.  3.]
Another optional argument is the shape to use for the array. When passed a NumArray instance, by default array will make an independent, aligned, contiguous, non-byteswapped copy. If also passed a shape or different type, the resulting ``copy'' will be reshaped or cast as the new type.

asarray( seq, type=None, typecode=None)
This function converts scalars, lists and tuples to a numarray, when possible. It passes numarrays through, making copies only to convert types. In any other case a TypeError is raised.

inputarray( seq, type=None, typecode=None)
This is an obosolete alias for asarray.


Important Tip

Pop Quiz: What will be the type of the array below:
>>> mystery = array([1, 2.0, -3j])
Hint: -3j is an imaginary number.
Answer: Complex64

A very common mistake is to call array with a set of numbers as arguments, as in array(1, 2, 3, 4, 5). This doesn't produce the expected result if at least two numbers are used, because the first argument to array must be the entire data for the array -- thus, in most cases, a sequence of numbers. The correct way to write the preceding invocation is most likely array([1, 2, 3, 4, 5]).

Possible values for the type argument to the array creator function (and indeed to any function which accepts a so-called type for arrays) are:

  1. Elements that can have values true or false: Bool.
  2. Unsigned numeric types: UInt8, UInt16, UInt32, and UInt644.1.
  3. Signed numeric types:
    • Signed integer choices: Int8, Int16, Int32, Int64.
    • Floating point choices: Float32, Float64.
  4. Complex number types: Complex32, Complex64.

To specify a type, e.g. UInt8, etc, the easiest method is just to specify it as a string:

a = array([10], type = 'UInt8')

The various means for specifying types are defined in table 4.1, with each item in a row being equivalent. The preferred methods are in the first 3 columns: numarray type object, type string, or type code. The last two columns were added for backwards compatabililty with Numeric and are not recommended for new code. Numarray type object and string names denote the size of the type in bits. The numarray type code names denote the size of the type in bytes. The type objects must be imported from or referenced via the numerictypes module. All type strings and type codes are specified using ordinary Python strings, and hence don't require an import. Complex type names denote the size of one component, real or imaginary, in bits/bytes, but the letter code is the total size of the whole number ('c8' and 'c16').


Table 4.1: Type specifiers
Numarray Type Numarray String Numarray Code Numeric String Numeric Code
Int8 'Int8' 'i1' 'Byte' '1'
UInt8 'UInt8' 'u1' 'UByte'  
Int16 'Int16' 'i2' 'Short' 's'
UInt16 'UInt16' 'u2' 'UShort'  
Int32 'Int32' 'i4' 'Int' 'i'
UInt32 'UInt32' 'u4' 'UInt' 'u'
Int64 'Int64' 'i8'    
UInt644.1 'UInt64' 'u8'    
Float32 'Float32' 'f4' 'Float' 'f'
Float64 'Float64' 'f8' 'Double' 'd'
Complex32 'Complex32' 'c8'   'F'
Complex64 'Complex64' 'c16' 'Complex' 'D'
Bool 'Bool'      


4.2.2 Multidimensional Arrays

The following example shows one way of creating multidimensional arrays:

>>> ma = array([[1,2,3],[4,5,6]])
>>> print ma
[[1 2 3]
 [4 5 6]]
The first argument to array in the code above is a single list containing two lists, each containing three elements. If we wanted floats instead, we could specify, as discussed in the previous section, the optional type we wished:
>>> ma_floats = array([[1,2,3],[4,5,6]], type=Float32)
>>> print ma_floats
[[ 1.  2.  3.]
 [ 4.  5.  6.]]
This array allows us to introduce the notion of ``shape''. The shape of an array is the set of numbers which define its dimensions. The shape of the array ma defined above is 2 by 3. More precisely, all arrays have an attribute which is a tuple of integers giving the shape. The getshape method returns this tuple. In general, one can directly use the shape attribute (but only for Python 2.2 and later) to get or set its value. Since it isn't supported for earlier versions of Python, subsequent examples will use getshape and setshape only. So, in this case:
>>> print ma.shape                      # works only with Python 2.2 or later
>>> print ma.getshape()                 # works with all Python versions
(2, 3)
Using the earlier definitions, this is a shape of rank 2, where the first axis has length 2, and the second axis has length 3. The rank of an array A is always equal to len(A.getshape()). Note that shape is an attribute and getshape is a method of array objects. They are the first of several that we will see throughout this tutorial. If you're not used to object-oriented programming, you can think of attributes as ``features'' or ``qualities'' of individual arrays, and methods are functions that operate on individual arrays. The relation between an array and its shape is similar to the relation between a person and their hair color. In Python, it's called an object/attribute relation.

reshape( a, shape)
What if one wants to change the dimensions of an array? For now, let us consider changing the shape of an array without making it ``grow''. Say, for example, we want to make the 2x3 array defined above (ma) an array of rank 1:
>>> flattened_ma = reshape(ma, (6,))
>>> print flattened_ma
[1 2 3 4 5 6]
One can change the shape of arrays to any shape as long as the product of all the lengths of all the axes is kept constant (in other words, as long as the number of elements in the array doesn't change):
>>> a = array([1,2,3,4,5,6,7,8])
>>> print a
[1 2 3 4 5 6 7 8]
>>> b = reshape(a, (2,4))               # 2*4 == 8
>>> print b
[[1 2 3 4]
 [5 6 7 8]]
>>> c = reshape(b, (4,2))               # 4*2 == 8
>>> print c
[[1 2]
 [3 4]
 [5 6]
 [7 8]]
The function reshape expects an array/sequence as its first argument, and a shape as its second argument. The shape has to be a sequence of integers (a list or a tuple). There is also a setshape method, which changes the shape of an array in-place (see below).

One nice feature of shape tuples is that one entry in the shape tuple is allowed to be -1. The -1 will be automatically replaced by whatever number is needed to build a shape which does not change the size of the array. Thus:

>>> a = reshape(array(range(25)), (5,-1))
>>> print a, a.getshape()
[[ 0  1  2  3  4]
 [ 5  6  7  8  9]
 [10 11 12 13 14]
 [15 16 17 18 19]
 [20 21 22 23 24]] (5, 5)
The shape of an array is a modifiable attribute of the array, but it is an internal attribute. You can change the shape of an array by calling the setshape method (or by assigning a tuple to the shape attribute, in Python 2.2 and later), which assigns a new shape to the array:
>>> a = array([1,2,3,4,5,6,7,8,9,10])
>>> a.getshape()
(10,)
>>> a.setshape((2,5))
>>> a.shape = (2,5)                     # for Python 2.2 and later
>>> print a
[[ 1  2  3  4  5]
 [ 6  7  8  9 10]]
>>> a.setshape((10,1))                  # second axis has length 1
>>> print a
[[ 1]
 [ 2]
 [ 3]
 [ 4]
 [ 5]
 [ 6]
 [ 7]
 [ 8]
 [ 9]
 [10]]
>>> a.setshape((5,-1))                  # note the -1 trick described above
>>> print a
[[ 1  2]
 [ 3  4]
 [ 5  6]
 [ 7  8]
 [ 9 10]]
As in the rest of Python, violating rules (such as the one about which shapes are allowed) results in exceptions:
>>> a.setshape((6,-1))
Traceback (innermost last):
  File "<stdin>", line 1, in ?
ValueError: New shape is not consistent with the old shape

For Advanced Users: Printing arrays

Sections denoted ``For Advanced Users'' indicates function aspects which may not be needed for a first introduction of numarray, but is mentioned for the sake of completeness.

The default printing routine provided by the numarray module prints arrays as follows:

  1. The last axis is always printed left to right.
  2. The next-to-last axis is printed top to bottom.
The remaining axes are printed top to bottom with increasing numbers of separators.

This explains why rank-1 arrays are printed from left to right, rank-2 arrays have the first dimension going down the screen and the second dimension going from left to right, etc.

If you want to change the shape of an array so that it has more elements than it started with (i.e. grow it), then you have several options: One solution is to use the concatenate function discussed later.

>>> print a
[0 1 2 3 4 5 6 6 7]
>>> print concatenate([[a],[a]])
>>> print b
[[0 1 2 3 4 5 6 7]
 [0 1 2 3 4 5 6 7]]
>>> print b.getshape()
(2, 8)

resize( array, shape)
A final possibility is the resize function, which takes a base array as its first argument and the desired shape as the second argument. Unlike reshape, the shape argument to resize can be a smaller or larger shape than the input array. Smaller shapes will result in arrays with the data at the ``beginning'' of the input array, and larger shapes result in arrays with data containing as many replications of the input array as are needed to fill the shape. For example, starting with a simple array
>>> base = array([0,1])
one can quickly build a large array with replicated data:
>>> big = resize(base, (9,9))
>>> print big
[[0 1 0 1 0 1 0 1 0]
 [1 0 1 0 1 0 1 0 1]
 [0 1 0 1 0 1 0 1 0]
 [1 0 1 0 1 0 1 0 1]
 [0 1 0 1 0 1 0 1 0]
 [1 0 1 0 1 0 1 0 1]
 [0 1 0 1 0 1 0 1 0]
 [1 0 1 0 1 0 1 0 1]
 [0 1 0 1 0 1 0 1 0]]



Footnotes

...UInt644.1
UInt64 is unsupported on Windows
Send comments to the NumArray community.