2 ¿QUÉ INCORPORA EL DIBUJO?
2.4. Tocar el límite
Python, by default, only has access to a small number of built-in types and functions. The vast majority of functions are located in modules, and before a function can be accessed, the module which contains the function must be imported. For example, when usingipython --pylab(or any variants), a large number of modules are automatically imported, including NumPy and matplotlib. This is style of importing useful for learning and interactive use, but care is needed to make sure that the correct module is imported when designing more complex programs.
importcan be used in a variety of ways. The simplest is to usefrom moduleimport *which imports
all functions in module. This method of usingimportcan dangerous since if you use it more than once, it is possible for functions to be hidden by later imports. A better method is to just import the required functions. This still places functions at the top level of the namespace, but can be used to avoid conflicts. from pylab import log2 # Will import log2 only
from scipy import log10 # Will not import the log2 from SciPy
The functionslog2andlog10can both be called in subsequent code. An alternative, and more common, method is to useimportin the form
import pylab
import scipy
import numpy
which allows functions to be accessed using dot-notation and the module name, for examplescipy.log2. It is also possible to rename modules when imported usingas
import pylab as pl
import scipy as sp
import numpy as np
The only difference between these two is thatimport scipyis implicitly callingimport scipy as scipy. When this form of import is used, functions are used with the “as” name. For example, the load provided by NumPy is accessed usingsp.log2, while the pylab load ispl.log2– and both can be used where appro- priate. While this method is the most general, it does require slightly more typing.
4.10
Calling Functions
Functions calls have different conventions than most other expressions. The most important difference is that functions can take more than one input and return more than one output. The generic structure
of a function call is out1, out2, out3, . . . = functionname(in1, in2, in3, . . .). The important aspects of this structure are
• If multiple outputs are returned, but only one output variable is provided, the output will (generally) be a tuple.
• If more than one output variable is given in a function call, the number of output must match the number of output provided by the function. It is not possible to ask for two output if a function re- turns three – using an incorrect number of outputs results inValueError: too many values to unpack. • Both inputs and outputs must be separated by commas (,)
• Inputs can be the result of other functions as long only one output is returned. For example, the following are equivalent,
>>> y = var(x) >>> mean(y)
and
>>> mean(var(x))
Required Arguments
Most functions have required arguments. For example, consider the definition ofarrayfromhelp(array),
array(object, dtype=None, copy=True, order=None, subok=False, ndmin=0)
Array has 1 required input,object, which is the list or tuple which contains values to use when creating the array. Required arguments can be determined by inspecting the function signature since all of the input follow the patters keyword=default exceptobject– required arguments will not have a default value provided. The other arguments can be called in order (arrayaccepts at most 2 non-keyword arguments).
>>> array([[1.0,2.0],[3.0,4.0]]) array([[ 1., 2.], [ 3., 4.]]) >>> array([[1.0,2.0],[3.0,4.0]], ’int32’) array([[1, 2], [3, 4]]) Keyword Arguments
All of the arguments toarraycan be called by their keyword, which is listed in the help file definition.
array(object=[[1.0,2.0],[3.0,4.0]])
array([[1.0,2.0],[3.0,4.0]], dtype=None, copy=True, order=None, subok=False, ndmin=0)
Keyword arguments have two important advantages. First, they do not have to appear in any order (Note: randomly ordering arguments is not good practice, and this is only an example), and second, keyword arguments can be used only when needed since a default value is always given.
>>> array(dtype=’complex64’, object = [[1.0,2.0],[3.0,4.0]], copy=True) array([[ 1.+0.j, 2.+0.j],
[ 3.+0.j, 4.+0.j]], dtype=complex64)
Default Arguments
Functions have defaults for optional arguments. These are listed in the function definition and appear in the help in the form keyword=default. Returning toarray, all inputs have default arguments except
object– the only required input.
Multiple Outputs
Some functions can have more than 1 output. These functions can be used in a single output mode or in multiple output mode. For example,shapecan be used on an array to determine the size of each dimen- sion.
>>> x = array([[1.0,2.0],[3.0,4.0]]) >>> s = shape(x)
>>> s (2L, 2L)
Since shape will return as many outputs as there are dimensions, it can be called with 2 outputs when the input is a 2-dimensional array.
>>> x = array([[1.0,2.0],[3.0,4.0]]) >>> M,N = shape(x) >>> M 2L >>> N 2L
Requesting more outputs than are required will produce an error.
>>> M,N,P = shape(x) # Error
ValueError: need more than 2 values to unpack
Similarly, providing two few output can also produce an error. Consider the case where the argument used with shape is a 3-dimensional array.
>>> x = randn(10,10,10) >>> shape(x)
(10L, 10L, 10L)
>>> M,N = shape(x) # Error
ValueError: too many values to unpack
4.11
Exercises
1. Input the following mathematical expressions into Python as both arrays and matrices.
v = 1 1 2 3 5 8 x = " 1 0 0 1 # y = " 1 2 3 4 # z = 1 2 1 2 3 4 3 4 1 2 1 2 w = " x x y y #
Note: A column vector must be entered as a 2-dimensional array. 2. What command would pull x out of w ? (Hint:w[?,?]is the same as x .) 3. What command would pull
x0 y00
out ofw? Is there more than one? If there are, list all alternatives. 4. What command would pull y out of z ? List all alternatives.
5. Explore the options for creating an array using keyword arguments. Create an array containing
y =
"
1 −2
−3 4
#
with combination of keyword arguments in:
(a) dtypeinfloat,float64,int32(32-bit integers),uint32(32-bit unsigned integers) andcomplex128 (double precision complex numbers).
(b) copyeitherTrueorFalse.
(c) ndimeither3or4. Useshape(y)to see the effect of this argument.
Chapter 5
Basic Math
Note: Python contains amathmodule providing functions which operate on built-in scalar data types (e.g.floatandcomplex). This and subsequent chapters assume mathematical functions must operate on arrays and matrices, and so are imported from NumPy.
5.1
Operators
These standard operators are available:
Operator Meaning Example Algebraic
+ Addition x + y x+ y
- Subtraction x - y x−y
* Multiplication x * y x y
/ Division (Left divide) x/y xy
** Exponentiation x**y xy
When xandyare scalars, the behavior of these operators is obvious. The only possible exception occurs when bothxandyare integers for division, wherex/yreturns the smallest integer less than the ratio (e.g. bxyc). The simplest method to avoid this problem is usefrom __future__ importdivision
which changes the default behavior. Alternatively, declaring numeric values to be floats using5.0rather than5will also mitigate this issue as well explicitly casting integers to floats before dividing.
>>> x = 9 >>> y = 5
>>> (type(x), type(y)) (int, int)
>>> x/y # Since division imported
1.8
>>> float(x)/y 1.8
Whenxandyare arrays or matrices, the behavior of mathematical operations is more complex. The examples in this chapter refer to arrays, and except where explicit differences are noted, it is safe to assume that the behavior of 2-dimensional arrays and matrices is identical.
I recommend using the import command from__future__ import divisionin all programs and IPython. The “future” division avoids this issue by always casting division to floating point when the result is not an exact integer.
5.2
Broadcasting
Under the normal rules of array mathematics, addition and subtraction are only defined for arrays with the same shape or between an array and a scalar. For example, there is no obvious method to add a 5-element vector and a 5 by 4 matrix. NumPy uses a technique called broadcasting to allow element-by-element mathematical operations on arrays (and matrices) which would not be compatible under the standard rules of array mathematics.
Arrays can be used in element-by-element mathematics ifxis broadcastable toy. Supposexis an m - dimensional array with dimensions d = [d1, d2. . . dm], andyis an n -dimensional array with dimensions
f = [f1, f2. . . fn] where m ≥ n . Formally, two arrays are broadcastable if the following two conditions
hold.
1. If m > n, then treatyas a m -dimensional array with size g = [1, 1, . . . , 1, f1, f2. . . fn] where the
number of 1s prepended is m −n . The dimensions are gi = 1 for i = 1, . . . m−n and gi = fi −m+n
for i > m−n .
2. For i = 1, . . . , m, max (di, gi) / min (di, gi)∈ {1, max(di, gi)}.
The first rule is simply states that if one array has fewer dimensions, it is treated as having the same num- ber of dimensions as the larger array by prepending 1s. The second rule states that arrays will only be broadcastable if either (a) they have the same dimension along axis i or (b) one has dimension 1 along axis i . When 2 arrays are broadcastable, the dimension of the output array is max(di, gi) for i = 1, . . . n.
Consider the following examples where m , n and p are assumed to have different values.
x y Broadcastable Output Size xOperation yOperation
Any Scalar Ø Same asx x tile(y,shape(x))
m , 1 1, n or n Ø m , n tile(x,(1,n)) tile(y,(m,1))
m , 1 n , 1 ×
m , n 1, n or n Ø m , n x tile(y,(m,1))
m , n , 1 1, 1, p or 1, p or p Ø m , n , p tile(x,(1,1,p)) tile(y,(m,n,1))
m , n , p 1, 1, p or 1, p or p Ø m , n , p x tile(y,(m,n,1))
m , n , 1 p , 1 ×
m , 1, p 1, n , 1, 1, n , p or n , 1 Ø m , n , p tile(x,(1,n,1)) tile(y,(m,1,p))
One simple method to visualize broadcasting is to use an add and subtract operation where the addition causes the smaller array to be broadcast, and then the subtract removes the values in the larger array. This will produce a replicated version of the smaller array which shows the nature of the broadcasting.
>>> x = array([[1,2,3.0]]) >>> x array([[ 1., 2., 3.]]) >>> y = array([[0],[0],[0.0]]) >>> y array([[ 0.], [ 0.], [ 0.]])
>>> x + y # Adding 0 produces broadcast
array([[ 1., 2., 3.], [ 1., 2., 3.], [ 1., 2., 3.]])
In the next example,xis 3 by 5, soymust be either scalar or a 5-element array or a 1×5 array to be broadcastable. Whenyis a 3-element array (and so matches the leading dimension), an error occurs.
>>> x = reshape(arange(15),(3,5)) >>> x array([[ 0, 1, 2, 3, 4], [ 5, 6, 7, 8, 9], [10, 11, 12, 13, 14]]) >>> y = 1 >>> x + y - x array([[5, 5, 5, 5, 5], [5, 5, 5, 5, 5], [5, 5, 5, 5, 5]]) >>> y = arange(5) >>> y array([0, 1, 2, 3, 4]) >>> x + y - x array([[0, 1, 2, 3, 4], [0, 1, 2, 3, 4], [0, 1, 2, 3, 4]]) >>> y = arange(3) >>> y array([0, 1, 2]) >>> x + y - x # Error
ValueError: operands could not be broadcast together with shapes (3,5) (3)