15.6 Array Objects
Numeric
provides an
array type that represents a grid of items. An
array object a has a
specified number of dimensions, known as its
rank, up to some arbitrarily high limit
(normally 40, when Numeric is
built with default options). A scalar (i.e., a single number) has
rank 0, a vector has rank 1, a
matrix has rank 2, and so
forth.
15.6.1 Type Codes
The
values that occupy cells in the grid of an array
object, known as the elements of the array, are
homogeneous, meaning they are all of the same type, and all element
values are stored within one memory area. This contrasts with a list
or tuple, where the items may be of different types and each is
stored as a separate Python object. This means a
Numeric array occupies far less memory than a
Python list or tuple with the same number of items. The type of
a's elements is encoded
as a's type code, a
one-character string, as shown in Table 15-3.
Factory functions that build array instances,
covered in Section 15.6.6
later in this chapter, take a typecode
argument that is one of the values in Table 15-3.
Table 15-3. Type codes for Numeric arrays
'c'
|
char
|
str (length 1)
|
Character
|
'b'
|
unsigned char
|
int
|
UnsignedInt8
|
'1'
|
signed char
|
int
|
Int8
|
's'
|
short
|
int
|
Int16
|
'i'
|
int
|
int
|
Int32
|
'l'
|
long
|
int
|
Int
|
'f'
|
float
|
float
|
Float32
|
'F'
|
two floats
|
complex
|
Complex32
|
'd'
|
double
|
float
|
Float
|
'D'
|
two doubles
|
complex
|
Complex
|
'O'
|
PyObject*
|
any
|
PyObject
|
Numeric supplies readable attribute names for each
type code, as shown in the last column of Table 15-3. Numeric also supplies, on
all platforms, the names Int0,
Float0, Float8,
Float16, Float64,
Complex0, Complex8,
Complex16, and Complex64. In
each case, the name refers to the smallest type of the requested kind
with at least that many bits. For example, Float8
is the smallest floating-point type of at least 8 bits (generally the
same as Float32, but some platforms may provide
very small floating-point types), while Complex0
is the smallest complex type. On some platforms, but not all,
Numeric also supplies the names
Int64, Int128,
Float128, and Complex128, with
similar meanings. These names are not supplied on all platforms
because not all platforms provide numbers with that many bits. The
next release of Numeric will also support unsigned
integer types.
A type code of 'O' indicates that elements are
references to Python objects. In this case, elements can be of
different types. This lets you use Numeric
array objects as Python containers, for advanced
array-processing tasks that may have nothing to do with numeric
processing. When you build an array a with
one of Numeric's factory
functions, you can either specify
a's type code explicitly
or accept a default data-dependent type code.
To get the type code of an array a, call
a.typecode( ).
a's type code determines
how many bytes each element of a takes up
in memory. Call a.itemsize(
) to get this information. When the type code is
'O', the item size is small (e.g., 4 bytes on a
32-bit platform), but this size accounts only for the reference held
in each of a's cells. The
objects indicated by the references are stored elsewhere as separate
Python objects; each such object may occupy an arbitrary amount of
extra memory, which is not accounted for in the item size of an array
with type code 'O'.
15.6.2 Shape and Indexing
Each array object
a has an attribute
a.shape, which is a
tuple of integer values.
len(a.shape)
is a's rank, so for
example, a one-dimensional array of numbers (also known as a
vector) has rank 1, and
a.shape has just one
item. More generally, each item of
a.shape is the length
of the corresponding dimension of a.
a's number of elements,
known as its size, is the product of all items
of a.shape. Each
dimension of a is also known as an
axis. Axis indices are from 0
up, as usual in Python. Negative axis indices are allowed and count
from the right, so -1 is the last (rightmost)
axis.
Each array a is a Python sequence. Each
item
a[i]
of a is a subarray of
a, meaning it is an array with a rank one
less than a's:
a[i].shape= =a.shape[1:]
For example, if a is a two-dimensional
matrix (a is of rank
2),
a[i],
for any valid index i, is a
one-dimensional subarray of a
corresponding to a row of the matrix. When
a's rank is
1 or 0,
a's items are
a's elements. Since
a is a sequence, you can index
a with normal indexing syntax to access or
change a's items. Note
that a's items are
a's subarrays; only for
an array of rank 1 or 0 are the
array's items the same thing as the
array's elements.
You can also use a in a
for loop, as for any other sequence. For example:
for x in a:
process(x)
means the same thing as:
for i in range(len(a)):
x = a[i]
process(x)
In these
examples, each item x of
a in the for loop is a
subarray of a. For example, if
a is a two-dimensional matrix, each
x in either of these loops is a
one-dimensional subarray of a
corresponding to a row of the matrix.
You can also index a by a tuple. For
example, if a's rank is
at least 2, you can write
a[i][j]
as
a[i,j]
for any valid i and
j, for rebinding as well as for access.
Tuple indexing is faster and more convenient. You do not need to use
parentheses inside the brackets in order to indicate that you are
indexing a by a tuple: it suffices to
write the indices one after the other, separated by commas. In other
words,
a[i,j]
means the same thing as
a[(i,j)],
but the syntax without the parentheses is more natural and readable.
If the result of indexing is a single number,
Numeric implicitly converts the result from a
rank-zero array to a scalar quantity of the appropriate Python type.
In other words, as a result of such an indexing you get a number, not
an array with one number in it. While this makes it convenient to
pass array elements to other non-Numeric software,
it also has unfortunate consequences, and this behavior will change
in numarray. With the present behavior,
special-casing is required. For example:
a[i].shape= =a.shape[1:]
does not execute correctly as Python code when
a's rank is
1. In this case,
a[i]
is just a number, and numbers don't have a
shape attribute. Thus, an
AttributeError exception
results.
15.6.3 Storage
An
array object a is
usually stored in a continuous memory area, with the elements one
after the other in what is traditionally called row-major order. This
means that, for example, when
a's rank is
2, the elements of
a's first row
(a[0]) come first,
immediately followed by those of
a's second row
(a[1]), and so on.
An array can be noncontiguous when it shares some of the storage of a
larger array, as covered in the following section Section 15.6.4. For example, if
a's rank is
2, the slice
b=a[:,0]
is the first column of a, and is stored
noncontiguously because it occupies some of the same storage as
a. In other words,
b[0] occupies the same
storage as a[0,0],
while b[1] occupies the
same storage as a[1,0],
which cannot be adjacent to the memory occupied by
a[0,0] when
a has more than one column.
Numeric handles both contiguous and noncontiguous
arrays transparently in most cases. In the rest of this chapter, I
will point out the rare exceptions where a contiguous array is
needed. When you want to copy a noncontiguous array
b into a new contiguous array
c, use method copy,
covered in Section 15.6.7 later in
this chapter.
15.6.4 Slicing
Arrays may
share some or all of their data with other arrays.
Numeric shares data between arrays whenever
feasible. If you want Numeric to copy data,
explicitly ask for a copy. Data sharing particularly applies to
slices. For built-in Python lists and standard library
array objects, slices are copies, but for
Numeric array objects, slices
share data with the array they're sliced from:
from Numeric import *
alist=range(10)
list_slice=alist[3:7]
list_slice[2]=22
print list_slice, alist # prints: [3,4,22,6] [0,1,2,3,4,5,6,7,8,9]
anarray=array(alist)
arr_slice=anarray[3:7]
arr_slice[2]=33
print arr_slice, anarray # prints: [ 3 4 33 6] [ 0 1 2 3 4 33 6 7 8 9]
Rebinding an item of list_slice does not affect
the list alist that list_slice
is sliced from, since for built-in lists, slicing performs a copy.
However, because for Numeric arrays, slicing
shares data, assigning to an item of arr_slice
does affect the array object
anarray that arr_slice is
sliced from. This behavior may be unexpected for a beginner, but was
chosen to enable high
performance.
15.6.4.1 Slicing examples
You can use a tuple to slice an array, just as you can to index it.
For arrays, slicing and indexing blend into each other. Each item in
a slicing tuple can be an integer, and the slice has one fewer axis
than the array being sliced. Slicing removes the axis for which you
give a number by selecting the indicated plane of the array.
A slicing tuple item can also be a slice expression; the general
syntax is
start:stop:step,
and you can omit one or more of the three parts (see
Section 4.6 in Chapter 4, and function slice in
Chapter 8, for details on slice semantics and
defaults). Here are some example slicings:
# a is [[ 0, 1, 2, 3, 4, 5],
# [10,11,12,13,14,15],
# [20,21,22,23,24,25],
# [30,31,32,33,34,35],
# [40,41,42,43,44,45],
# [50,51,52,53,54,55]]
a[0,2:4) # array([2,3])
a[3:,3:] # array([[33,34,35],
# [43,44,45],
# [53,54,55]])
a[:,4] # array([4,14,24,34,44,54])
a[2::2,::2] # array([[20,22,24],
# [40,42,44]])
A slicing-tuple item can also use an ellipsis
(...) to indicate that the following items in the
slicing tuple apply to the last (rightmost) axes of the array
you're slicing. For example, consider slicing an
array b of rank 3:
b.shape # (4,2,3)
b[1].shape # (2,3)
b[...,1].shape # (4,2)
When we slice with b[1] (equivalent to indexing),
we give an integer index for axis 0, and therefore
we select a specific plane along
b's axis 0. By
selecting a specific plane, we remove that axis from the
result's shape. Therefore, the
result's shape is b.shape[1:].
When we slice with b[...,1], we select a specific
plane along b's axis
-1 (the rightmost axis of b).
Again, by selecting a specific plane, we remove that axis from the
result's shape. Therefore, the
result's shape in this case is
b.shape[:-1].
A slicing-tuple item can also be the pseudo-index
NewAxis. The resulting slice has an additional
axis at the point at which you use NewAxis, with a
value of 1 in the corresponding item of the shape
tuple. Continuing the previous example:
b[NewAxis,...,NewAxis].shape # (1,4,2,3,1)
Here, rather than selecting and thus removing some of
b's axes, we have added two new
axes, one at the start of the shape and one at the end, thanks to the
ellipsis.
Axis removal and addition can both occur in the same slicing. For
example:
b[NewAxis,:,0,:,NewAxis].shape # (1,4,3,1)
Here, we both add new axes at the start and end of the shape, and
select a specific index from the middle axis (axis
1) of b by giving an index for
that axis. Therefore, axis 1 of
b is removed from the result's
shape. The colons (:) used as the second and
fourth items in the slicing tuple in this example are slice
expressions with both start and
stop omitted, meaning that all of the
corresponding axis is included in the slice. In all these examples,
all slices share some or all of
b's data. Slicing affects only
the shape of the resulting array. No data is copied, and no
operations are performed on the data.
15.6.4.2 Assigning to array slices
Assignment to array slices is less
flexible than assignment to list slices. Normally, you can assign to
an array slice only another array of the same shape as the slice.
However, if the right-hand side of the assignment is not an array,
Numeric implicitly creates a temporary array from
it. Each element of the right-hand side is coerced to the left-hand
side's type. If the right-hand side array is not the
same shape as the left-hand side slice, broadcasting applies, as
covered in Section 15.6.8
later in this chapter. So, for example, you can assign a scalar (a
single number) to any slice of a numeric array. In this case, the
right-hand side number is coerced, then broadcast (replicated) as
needed to make the assignment succeed.
When you assign to an array slice (or indexing) a right-hand side of
a type different from that of the left-hand side,
Numeric coerces the values to the left-hand
side's type, for example by truncating
floating-point numbers to integers. This does not apply if the
right-hand side values are complex. Full coercion does not apply to
in-place operators, which can only cast the right-hand side values
upwards (for example, an integer right-hand side may be used for
in-place operations with a floating-point left-hand side, but not
vice versa), as covered in Section 15.6.8.2 later in this chapter.
15.6.5 Truth Values
Although an array object
a is a Python sequence, in recent versions
of Numeric a does not
follow Python's normal rule for truth values of
sequences, where
bool(a)
depends only on
len(a)
and not on a's elements
(i.e., the rule by which any sequence is false only when empty,
otherwise it is true). Rather, a is false
when a has no elements or all of
a's elements are numeric
0. This lets you test for element-wise equality of
arrays in the natural way:
if a= =b:
Without this proviso, such an if condition would
be satisfied by any non-empty comparable arrays
a and b.
Do remember, however, that you have to be explicit when you want to
test whether a has any items or whether
a has any elements, as these are two
different conditions:
a = Numeric.array( [ [ ], [ ], [ ] ] )
if a: print 'a is true'
else: print 'a is false' # prints: a is false
if len(a): print 'a has some items'
else: print 'a has no items' # prints: a has some items
if Numeric.size(a): print 'a has some elements'
else: print 'a has no elements' # prints: a has no elements
In most
cases, the best way to compare arrays of numbers is for approximate
equality with function allclose, covered later in
this chapter.
15.6.6 Factory Functions
Numeric supplies numerous factory functions that
create array objects.
array(data,typecode=None,copy=True,savespace=False)
|
|
Returns a new array object
a.
a's shape depends on
data. When data
is a number, a has rank
0 and
a.shape is the empty
tuple ( ). When data is
a sequence of numbers, a has rank
1 and
a.shape is the
singleton tuple
(len(data),).
When data is a sequence of sequences of
numbers, all of data's
items must have the same length, a has
rank 2, and
a.shape is the pair
(len(data),len(data[0])).
This idea generalizes to any nesting level of
data as a sequence of sequences, up to the
arbitrarily high limit on rank mentioned earlier in this chapter. If
data is nested over that limit, array raises
TypeError. (This is unlikely to be a problem in
practice, as an array of rank at least 40, with
each axis of length at least 2, would have well
over a million of millions of elements).
typecode can be any of the values shown in
Table 15-2 or None. When
typecode is None,
array chooses a default type code depending on the
types of the elements of data. When any
one or more elements in data are long
integer values or are neither numbers nor plain strings (e.g.,
None or Unicode strings), the type code is
PyObject. When all elements are plain strings, the
type code is Character. When any one or more
elements (but not all) are plain strings, all others are numbers (not
long integers), and typecode is
None, array raises
TypeError. You must explicitly pass
'O' or PyObject as argument
typecode if you want to have
array build an array from some plain strings and
some non-long integers. When all elements are numbers (not long
integers), the default type code depends on the widest numeric type
among the elements. When any of the elements is a
complex, the type code is
Complex. When no elements are complex but some are
floating-point values, the type code is Float.
When all elements are integers, the type code is
Int.
Function array, by default, returns an
array object a that
doesn't share data with others. If
data is an array
object, and you explicitly pass a false value for argument
copy, array returns an
array object a that
shares data with data, if feasible.
By default, an array object with a numeric type
code is implicitly cast up when operated with numbers of wider
numeric types. When you do not need this implicit casting, you can
save some memory by explicitly passing a true value for argument
savespace to the array
factory function, to set the resulting array
object a into space-saving mode. For
example:
array(range(4),typecode='b')+2.0 # array([2.,3.,4.,5.])
array(range(4),typecode='b',savespace=True)+2.0
# array([2,3,4,5])
array(range(4),typecode='b',savespace=True)+258.7
# array([2,3,4,5]) The first statement creates an array of floating-point values, as
savespace is not specified and thus each
element is implicitly cast up to a float when
added to 2.0. The second and third statements
create arrays of 8-bit integers, since
savespace is specified. Therefore, instead
of implicit casting up of the array's element, we
get implicit casting down of the float added to
each element. 258.7 is cast down to
2: the fractional part .7 is
lost because of the cast to an integer, and the resulting
258 becomes 2 because, since
the cast is to 8-bit integers, only the lowest 8 bits are kept. The
savespace mode can be very useful for
large arrays, but be careful lest you suffer unexpected loss of
precision when using it.
arrayrange([start,]stop[,step=1],typecode=None)
|
|
Like
array(range(start,stop,step),typecode),
but faster. See built-in function range, covered
in Chapter 8, for details about
start, stop,
and step. arrayrange
allows float values for these arguments, not just
int values. Be careful when exploiting this
feature, since the approximations inherent in floating-point
arithmetic may lead to a result with one more or fewer items than you
might expect. arange is a synonym of
arrayrange.
fromstring(data,count=None,typecode=Int)
|
|
Returns a one-dimensional array a of shape
(count,)
with data copied from the bytes of string
data. When
count is None,
len(data)
must be a multiple of
typecode's item size, and
a's shape is
(len(data)/a.itemsize(
),). When count is not
None,
len(data)
must be greater than or equal to
count*a.itemsize(
), and fromstring ignores
data's trailing bytes, if
any.
Together with methods
a.tostring and
a.byteswapped (covered
in the following section Section 15.6.7), function
fromstring allows binary input/output of
array objects. When you need to save arrays and
later reload them, and don't need to use the saved
form in non-Python programs, it's simpler and faster
to use module cPickle, covered in Chapter 11. Many experienced users prefer to use a
portable self-describing file format such as
netCDF (see http://met-www.cit.cornell.edu/noon/ncmodule.html).
Returns a two-dimensional array a of shape
(n,n).
a's elements are
0, except those on the main diagonal
(a[j,j]
for j in
range(n)),
which are 1.
ones(shapetuple,typecode=Int,savespace=False)
|
|
Returns an array a such that
a.shape=
=shapetuple. All of
a's elements are
1.
zeros(shapetuple,typecode=Int,savespace=False)
|
|
Returns an array a such that
a.shape=
=shapetuple. All of
a's elements are
0.
Note that, by default, identity,
ones, and zeros all return
arrays whose type is Int. Be sure to specify
explicitly a different type code, such as Float,
if that is what you really want. For example, be sure to avoid the
following common mistake:
a = zeros(3)
a[0] = 0.3 # a is array([0,0,0])
Since a is Int in this snippet,
the 0.3 we assign to one of its items gets
truncated to the integer 0. Instead, you typically
want something closer to the following:
a = zeros(3,Float)
a[0] = 0.3 # a is array([0.3,0.,0.])
Here, we have explicitly specified Float as the
type code for a, and therefore no truncation
occurs when we assign 0.3 to one of
a's items.
15.6.7 Attributes and Methods
For most
array manipulations, Numeric supplies functions
you can call with array arguments. You can also use Python lists as
arguments; this polymorphism offers flexibility that is not available
for functionality packaged up as array attributes and methods. Each
array object a also
supplies some methods and attributes, for direct access to
functionality that would not benefit from polymorphic possibilities.
Returns a new array b with the same shape
as a.
b's elements are
a's elements coerced to
the type indicated by typecode.
b does not share
a's data, even if
typecode equals
a.typecode( ).
Returns a new array object
b with the same type code and shape as
a. Each element of
b is copied from the corresponding element
of a, inverting the order of the bytes in
the value. This swapping transforms each value from little-endian to
big-endian or vice versa. Together with function
fromstring and method
a.tostring, this helps
when you have binary data from one kind of machine and need them for
the other kind (for example, Intel platforms are little-endian, while
Sun platforms are big-endian).
Returns a new contiguous array object
b, identical to
a, but not sharing
a's data.
a .flat is an
attribute that contains an array with rank of one less than
a and of the same size as
a, sharing
a's data. Indexing or
slicing a.flat lets you
access or change a's
elements through this alternate view of a.
Trying to access a.flat
raises a TypeError exception if
a is noncontiguous. When
a is contiguous,
a.flat is in row-major
order. This means that, for example, when
a's shape is
(7,4) (i.e., a is a
two-dimensional matrix with seven rows and four columns),
a.flat[i]
is the same as
a[divmod(i,4)]
for all i in range(28).
Trying to access the
a.real and
a.imag attributes
raises a TypeError exception unless
a's type code is complex.
When a's type code is
complex, each of a.real
and a.imag is a
noncontiguous array with the same shape as
a and a float type
code, sharing data with a. By accessing or
modifying a.real or
a.imag, you access or
modify the real or imaginary parts of
a's complex-number
elements. imaginary is a synonym of
imag.
Returns True if
a's data occupies
contiguous storage, otherwise False. This matters
particularly when interfacing to C-coded extensions.
a.copy( ) makes a
contiguous copy of a. Noncontiguous arrays
arise when slicing or transposing arrays, as well as for attributes
a.real and
a.imag of an array
a with a complex type code.
Returns the number of bytes of memory used by each of
a's elements (not by each
of a's items, which are
subarrays of a).
Sets or resets the space-saving mode of array
a, depending on the truth value of
flag. When flag
is true,
a.savespace(flag)
sets a's space-saving
mode so that a's elements
are not implicitly cast up when operated with arrays of wider numeric
types. For more details on this, see the discussion of
savespace for function
array earlier in this chapter. When
flag is false,
a.savespace(flag)
resets a's space-saving
mode so that a's elements
are implicitly cast up when needed.
The
a.shape attribute is a
tuple with one item per axis of a, giving
the length of that axis. You can assign a sequence of integers to
a.shape to change the
shape of a, but
a's size (the total
number of elements) must remain the same. When you assign to
a.shape another
sequence s, one of
s's items can be
-1, meaning that the length along that axis is
whatever is needed to keep
a's size unchanged.
However, the product of the other items of
s must evenly divide
a's size, or else the
reshaping raises an exception. When you need to change the total
number of elements in a, call function
resize (covered in Section 15.6.9 later in this chapter).
Returns True if
space-saving mode is on for array a,
otherwise False. See the discussion of
savespace for function
array earlier in this chapter.
Returns a list L equivalent to
a. For example, if
a.shape is
(2,3) and
a's type code is
'd', L is a list of two
lists of three float values each. In other words,
for each valid i and
j,
L[i][j]=
=a[i,j].
Note that
list(a)
converts only the top-level (axis 0) of array
a into a list, and thus is not equivalent
to a.tolist( ) if
a's rank is
2 or more. For example:
a=array([[1,2,3],[4,5,6]],typecode='d')
print a.shape # prints: (2,3)
print a # prints: [[1. 2. 3.]
# [4. 5. 6.]]
print list(a)
# prints: [array([1.,2.,3.]), array([4.,5.,6.])]
print a.tolist( )
# prints: [[1.0,2.0,3.0],[4.0,5.0,6.0]]
Returns a binary string s whose bytes are
a copy of the bytes of
a's elements.
Returns the type code of a as a
one-character string.
15.6.8 Operations on Arrays
Arithmetic operators
+, -, *,
/, %, and
**, comparison operators >,
>=, <,
<=, = =, and
!=, and bitwise operators
&, |, ^,
and ~ (all covered in Chapter 4) also apply to arrays. If both operands
a and b are
arrays with equal shapes and type codes, the result is a new array
c with the same shape and type code. Each
element of c is the result of the operator
on corresponding elements of a and
b (element-wise operation).
Arrays do not follow sequence semantics for *
(replication) and + (concatenation), but rather
use * and + for element-wise
arithmetic. Similarly, * does not mean matrix
multiplication, but element-wise multiplication.
Numeric supplies functions to perform replication,
concatenation, and matrix multiplication; all operators on arrays
perform element-wise operations.
When the type codes of a and
b differ, the narrower numeric type is
converted to the wider one, like for other Python numeric operations.
As usual, operations between numeric and non-numeric values are
disallowed. In the case of arrays, you can inhibit casting up by
setting an array into space-saving mode with method
savespace. Use space-saving mode with care, since
it can result in silent loss of significant data. For more details on
this, see the discussion of savespace for
function array earlier in this chapter.
15.6.8.1 Broadcasting
Element-wise operations between arrays of different shapes are
generally not possible: attempting such operations raises an
exception. Numeric allows some such operations by
broadcasting (replicating) a smaller array up to the shape of the
larger one when feasible. To make broadcasting efficient, the
replication is only conceptual: Numeric does not
need to physically copy the data being broadcast (i.e., you need not
worry that performance will be degraded because an operation involves
broadcasting).
The
simplest case of broadcasting is when one operand,
a, is a scalar (an array of rank
0), while b, the other
operand, is an array. In this case, Numeric
conceptually builds a temporary array t,
with shape b.shape,
where each element of t equals
a. Numeric then
performs the requested operation between t
and b. In practice, therefore, when you
operate an array b with a scalar
a, as in
a+b
or
b+a,
the resulting array has the same shape as
b, and each element is the result of
applying the operator to the corresponding element of
b and the single number
a.
More generally, broadcasting can also apply when both operands
a and b are
arrays. Conceptually, broadcasting works according to rather
complicated general rules:
When a and b
differ in rank, the one whose shape tuple is shorter is padded up to
the other's rank by adding leading axes, each with a
length of 1.
a.shape and
b.shape, padded to the
same length as per rule 1, are compared starting from the right
(i.e., from the length of the last axis).
When the axis length along the axis being examined is the same for
a and b, that
axis is okay, and examination moves leftward to the previous axis.
When the lengths of the axes differ and both are greater than
1, Numeric raises an exception.
When one axis length is 1,
Numeric broadcasts the corresponding array by
replication along that plane to the axis length of the other array.
Broadcasting's rules are complicated because of
their generality, but most typical applications of broadcasting are
in simple cases. For example, say we compute
a+b,
and a.shape is
(5,3) (a matrix of five rows, three columns).
Further, say typical values for
b.shape include
( ) (a scalar), (3,) (a
one-dimensional vector with three elements), and
(5,1) (a matrix with five rows, one column). In
each of these cases, b is broadcast up to
a temporary array t with shape
(5,3) by replicating
b's elements along the
needed axis (both axes, when b is a
scalar), and Numeric computes
a+t.
The simplest and most frequent case, of course, is when
b.shape is
(5,3), the same shape as
a's. In this case, no
broadcasting is needed.
15.6.8.2 In-place operations
Arrays
support in-place operations through augmented assignment operators
+=, -=, and so on. The
left-hand side array or slice cannot be broadcast, but the right-hand
side can be. Similarly, the left-hand side cannot be cast up, but the
right-hand side can be. In other words, in-place operations treat the
left-hand side as rigid in both shape and type, but the right-hand
side is subject to the normal, more lenient rules.
15.6.9 Functions
Numeric defines several functions that operate on
arrays, or polymorphically on Python sequences, conceptually forming
temporary arrays from non-array operands.
allclose(x,y,rtol=1.e-5,atol=1.e-8)
|
|
Returns True when every element of
x is close to the corresponding element of
y, otherwise False. Two
elements ex and
ey are defined to be close if:
abs(ex-ey)<atol+rtol*abs(ey) In other words, ex and
ey are close if both are tiny (less than
atol) or if the relative difference is
small (less than rtol).
allclose is generally a better way to check array
equality than = =, since floating-point arithmetic
requires some comparison tolerance. However,
allclose is not applicable to complex arrays, only
to floating-point and integer arrays. To compare two complex arrays
x and y for
approximate equality, you can use:
allclose(x.real, y.real) and allclose(x.imag, y.imag)
argmax(a,axis=-1)
argmin(a,axis=-1)
|
|
argmax returns a new integer array
m whose shape tuple is
a.shape minus the
indicated axis. Each element of
m is the index of a maximal element of
a along axis.
argmin is similar, but indicates minimal elements
rather than maximal ones.
Returns a new integer array m with the
same shape as a. Each vector of
m along axis is
the index sequence needed to sort the corresponding axis of
a. In particular, if
a has rank 1, the most
common case,
take(a,argsort(a))=
=sort(a). For
example:
x = [52, 115, 99, 111, 114, 101, 97, 110, 100, 55]
print Numeric.argsort(x) # prints: [0 9 6 2 8 5 7 3 4 1]
print Numeric.sort(x)
# prints: [52 55 97 99 100 101 110 111 114 115]
print Numeric.take(x, Numeric.argsort(x))
# prints: [52 55 97 99 100 101 110 111 114 115] Here, the result of
Numeric.argsort(x)
tells us that x's
smallest element is
x[0], the second
smallest is x[9], the
third smallest is x[6],
and so on. The call to Numeric.take in the last
print statement takes
x's elements exactly in
this order, and therefore produces the same sorted array as the call
to Numeric.sort in the second
print statement.
array2string(a,max_line_width=None,precision=None,
suppress_small=None,separator=' ',
array_output=False)
|
|
Returns a string representation s of array
a, showing elements within brackets,
separated by string separator. The last
dimension is horizontal, the penultimate one vertical, and further
dimensions are denoted by bracket nesting. If
array_output is true,
s starts with 'array('
and ends with ')'. s
ends with ",'X')" instead if X,
which is a's type code,
is not Float, Complex, or
Int, which lets you later use
eval(s)
if separator is ','.
Lines longer than max_line_width (by
default, 77) are broken up.
precision determines how many digits are
used per element (by default, 8). If
suppress_small is true, very small numbers
are shown as 0. You can change these defaults by
binding attributes of module sys named
output_line_width,
float_output_precision, and
float_output_suppress_small.
str(a)
is like
array2string(a).
repr(a)
is like
array2string(a,separator=',
',array_output=True).
average(a,axis=0,weights=None,returned=False)
|
|
Returns a's average along
axis. When axis
is None, returns the average of all
a's elements. When
weights is not None,
weights must be an array with
a's shape, or a
one-dimensional array with the length of
a's given
axis, and average
computes a weighted average. When returned
is true, returns a pair: the first item is the average, the second
item is the sum of weights (the count of values, when
weights is None).
Returns an array c with the same shape as
a. values is a
sequence. a's elements
are integers between 0, included, and
len(values),
excluded. Each element of c is the item of
values whose index is the corresponding
element of a. For example:
print Numeric.choose(Numeric.identity(3),'ox')
# prints: [[x o o]
# [o x o]
# [o o x]]
Returns an array c with the same type code
and shape as a. Each element
ec of c is the
corresponding element ea of
a, where
min<=ea<=max.
Where
ea<min,
ec is min;
where
ea>max,
ec is max. For
example:
print Numeric.clip(Numeric.arange(10),2,7)
# prints: [2 2 2 3 4 5 6 7 7 7]
compress(condition,a,axis=0)
|
|
Returns an array c with the same type code
and rank as a.
c includes only the elements of
a for which the item of
condition, corresponding along the given
axis, is true. For example,
compress((1,0,1),a)
= =
take(a,(0,2),0)
since (1,0,1) has true values only at indices
0 and 2.
Here's how to get only the even numbers from an
array:
a = Numeric.arange(10)
print Numeric.compress(a%2= =0, a) # prints: [0 2 4 6 8]
concatenate(arrays, axis=0)
|
|
arrays is a sequence of arrays, all with
the same shape except possibly along the given
axis. concatenate
returns an array that is the concatenation of the
arrays along the given
axis. In particular,
concatenate((s,)*n) has the same sequence
replication semantics that
s*n
would have if s were a generic Python
sequence rather than an array. For example:
print Numeric.concatenate([Numeric.arange(5),
Numeric.arange(3)])
# prints: [0 1 2 3 4 0 1 2]
Returns an array c with rank
1, the linear convolution of rank
1 arrays a and
b. Linear convolution is defined over
unbounded sequences. convolve conceptually extends
a and b to
infinite length by padding with 0, then clips the
infinite-length result to its central part, yielding
c. When mode is
2, the default, convolve clips
only the padding, so c's
shape is
(len(a)+len(b)-1,).
Otherwise, convolve clips more. Say
len(a)
is greater than or equal to
len(b):
when mode is 0,
len(c)
is
len(a)-len(b)+1;
when mode is 1,
len(c)
is
len(a).
When
len(a)
is less than
len(b),
the effect is symmetrical. For example:
a = Numeric.arange(6)
b = Numeric.arange(4)
print Numeric.convolve(a, b)
# prints: [0 0 1 4 10 16 22 22 15]
print Numeric.convolve(a, b, 1)
# prints: [0 1 4 10 16 22]
print Numeric.convolve(a, b, 0) # prints: [4 10 16]
cross_correlate(a,b,mode=0)
|
|
Like
convolve(a,b[::-1],mode).
diagonal(a,k=0,axis1=0,axis2=1)
|
|
Returns the elements of a whose index
along axis1 and index along
axis2 differ by
k. When a has
rank 2, this means the main diagonal when
k equals 0,
subdiagonals above the main one when k is
greater than 0, and subdiagonals below the main
one when k is less than
0. For example:
# a is [[0 1 2 3]
# [4 5 6 7]
# [8 9 10 11]
# [12 13 14 15]]
print Numeric.diagonal(a) # prints: [0 5 10 15]
print Numeric.diagonal(a,1) # prints: [1 6 11]
print Numeric.diagonal(a,-1) # prints: [4 9 14] As shown,
diagonal(a)
is the main diagonal,
diagonal(a,1)
the subdiagonal just above the main one, and
diagonal(a,-1)
the subdiagonal just below the main one.
indices(shapetuple,typecode=None)
|
|
Returns an integer array x of shape
(len(shapetuple),)+shapetuple.
Each element of subarray
x[i]
is equal to the element's
i index in the subarray. For example:
print Numeric.indices((2,4)) # prints: [[[0 0 0 0]
# [1 1 1 1]]
# [[0 1 2 3]
# [0 1 2 3]]]
Returns an array m with the result of the
inner product of a and
b, like
matrixmultiply(a,transpose(b)).
a.shape[-1] must equal
b.shape[-1], and
m.shape is the tuple
a.shape[:-1]+b.shape[0:-1:-1].
Returns an array m with
a times b in
the matrix-multiplication sense, rather than element-wise
multiplication.
a.shape[-1] must equal
b.shape[0], and
m.shape is the tuple
a.shape[:-1]+b.shape[1:].
Returns the indices of those elements of a
that are not equal to 0, like the expression:
array([i for i in range(len(a)) if a[i] != 0]) a must be a sequence or one-dimensional
array.
a must be a contiguous array.
indices is a sequence of integers, taken
as indices into a.flat.
values is a sequence of values that can be
converted to a's type
code (if shorter than indices,
values is repeated as needed). Each
element of a indicated by an item in
indices is replaced by the corresponding
item in values. put is
therefore similar to (but faster than) the loop:
for i,v in zip(indices,values*len(indices)):
a.flat[i]=v
a must be a contiguous array.
mask is a sequence with the same length as
a.flat.
values is a sequence of values that can be
converted to a's type
code (if shorter than mask,
values is repeated as needed). Each
element of a corresponding to a true item
in mask is replaced by the corresponding
item in values. putmask
is therefore similar to (but faster than) the loop:
for i,v in zip(xrange(len(mask)),values*len(mask)):
if mask[i]: a.flat[i]=v
Returns the rank of a, just like
len(array(a,copy=False).shape).
Returns the flat form of a, just like
array(a,copy=False).flat.
Returns an array with the same type code and rank as
a, where each of
a's elements is repeated
along axis as many times as the value of
the corresponding element of repeat.
repeat is an integer, or an integer
sequence of length
a.shape[axis].
Returns an array r with shape
shapetuple, sharing
a's data.
r=reshape(a,shapetuple)
is just like
r=a;r.shape=shapetuple.
The product of
shapetuple's items must
equal the product of
a.shape's,
but one of shapetuple's
items may be -1 to ask for adaptation of that
axis's length. For example:
print Numeric.reshape(range(12),(3,-1))
# prints: [[0 1 2 3]
# [4 5 6 7]
# [8 9 10 11]]
Returns an array r with shape
shapetuple and data copied from
a. If
r's size is smaller than
a's size,
r.flat is copied from
the start of
ravel(a);
if r's size is larger,
the data in
ravel(a)
is replicated as many times as needed. In particular,
resize(s,(n*len(s),))
has the sequence replication semantics that
s*n
would have if s were a generic Python
sequence rather than an array. For example:
print Numeric.resize(range(5),(3,4))
# prints: [[0 1 2 3]
# [4 0 1 2]
# [3 4 0 1]]
a must be a sorted rank
1 array. searchsorted returns
an array of integers s with the same shape
as values. Each element of
s is the index in
a where the corresponding element of
values would fit in the sorted order of
a. For example:
print Numeric.searchsorted([0,1],
[0.2,-0.3,0.5,1.3,1.0,0.0,0.3])
# prints: [1 0 1 2 1 0 1] This specific idiom returns an array with 0 in
correspondence to each element x of
values when x
is less than or equal to 0; 1
when x is greater than
0 and less than or equal to 1;
and 2 when x is greater
than 1. With slight generalization, and with
appropriate thresholds as the elements of sorted array
a, this idiom allows very fast
classification of what subrange each element
x of values
falls into.
Returns the shape of a, just like
array(a,copy=False).shape.
When axis is None,
returns the total number of elements in a.
Otherwise, returns the number of elements of
a along axis,
like
array(a,copy=False).shape[axis].
Returns an array s with the same type code
and shape as a, with elements along each
plane of the given axis reordered so that
the plane is sorted in increasing order. For example:
# x is [[0 1 2 3]
# [4 0 1 2]
# [3 4 0 1]]
print Numeric.sort(x) # prints: [[0 1 2 3]
# [0 1 2 4]
# [0 1 3 4]]
print Numeric.sort(x,0) # prints: [[0 0 0 1]
# [3 1 1 2]
# [4 4 2 3]] sort(x)
returns a result where each row is sorted.
sort(x,0)
returns a result where each column is sorted.
Returns an array s with the same type
code, rank, and size as a, sharing
a's data.
s's shape is the same as
a, but with the lengths of axes
axis1 and axis2
swapped. In other words,
s=swapaxes(a,axis1,axis2)
is like:
swapped_shape=range(length(a.shape))
swapped_shape[axis1]=axis2
swapped_shape[axis2]=axis1
s=transpose(a,swapped_shape)
Returns an array t with the same type code
and rank as a, containing the subset of
a's elements that would
be in a slice along axis comprising the
given indices. For example, after
t=take(a,(1,3)),
t.shape=
=(2,)+a.shape[1:],
and t's elements are
those in the second and fourth rows of a.
Returns the sum of a's
elements along the k diagonal, like
sum(diagonal(a,k)).
Returns an array t, with the same type
code, rank, and size as a, sharing
a's data.
t's axes are permuted
with respect to a's by
the axis indices in sequence axes. When
axes is None,
t's axes invert the order
of a's, as if
axes were
a.shape[::-1].
Returns an array w with the same shape as
condition. Where an element of
condition is true, the corresponding
element of w is the corresponding element
of x; otherwise it is the corresponding
element of y. For example,
clip(a,min,max)
is the same as
where(greater(a,max),max,where(greater(a,min),a,min)).
|