Docsity
Docsity

Prepare for your exams
Prepare for your exams

Study with the several resources on Docsity


Earn points to download
Earn points to download

Earn points by helping other students or get them with a premium plan


Guidelines and tips
Guidelines and tips

An Introduction to NumPy: Array Operations and Broadcasting, Exams of Logic

An overview of NumPy, a powerful library for numerical computations in Python. It covers the creation of n-dimensional arrays, universal functions for element-wise operations, and the concepts of vectorization and broadcasting. Examples are given to illustrate the usage of NumPy for basic arithmetic, summation, and array reshaping.

Typology: Exams

2021/2022

Uploaded on 09/12/2022

butterflymadam
butterflymadam 🇺🇸

4.4

(26)

312 documents

1 / 11

Toggle sidebar

This page cannot be seen from the preview

Don't miss anything!

bg1
09/10/2019&
1&
NumPy
Provides:
- true n-dimensional arrays (careful: 1-D arrays are not 1-D matrices)
- operations on those arrays: math, logical, sorting, etc
- discrete Fourier transform
- basic linear algebra
- basic statistics
- basic simulation
Arrays (ndarray)
- Fixed size: size changing involves copying and deletion of older array
- Homogeneous: all elements of the same type
but that type could be “Python object”, so it may be a size changing object,
of course obtained through indirection: it is not the intended use, however
Universal functions (ufunc)
operate in a uniform way on those arrays, usually element-wise (element per
element)
Two main mechanisms:
vectorization: loops are implicit
broadcasting: in certain situations the shape of an array is “adapted” to the
context
import numpy as np
Preliminary examples: (file lez-1.py)
a=np.array([1,2,3])
b=np.array([4,5,6])
c=a+b
instead of the loop [vectorisation of a universal function]
c=[]
for i in len(a):
c.append(a[i]*b[i])
if a and b are multidimensional, nested loop
broadcasting:
pf3
pf4
pf5
pf8
pf9
pfa

Partial preview of the text

Download An Introduction to NumPy: Array Operations and Broadcasting and more Exams Logic in PDF only on Docsity!

NumPy

Provides:

  • true n-dimensional arrays (careful: 1-D arrays are not 1-D matrices)
  • operations on those arrays: math, logical, sorting, etc
  • discrete Fourier transform
  • basic linear algebra
  • basic statistics
  • basic simulation Arrays ( ndarray )
  • Fixed size: size changing involves copying and deletion of older array
  • Homogeneous: all elements of the same type

but that type could be “Python object”, so it may be a size changing object,

of course obtained through indirection: it is not the intended use, however

Universal functions ( ufunc )

operate in a uniform way on those arrays, usually element-wise (element per

element)

Two main mechanisms:

vectorization: loops are implicit

broadcasting: in certain situations the shape of an array is “adapted” to the

context

import numpy as np

Preliminary examples: (file lez- 1 .py)

a=np.array([1,2,3])

b=np.array([4,5,6]) c=a+b

instead of the loop [vectorisation of a universal function]

c=[]

for i in len(a): c.append(a[i]*b[i])

if a and b are multidimensional, nested loop

broadcasting:

d=np.array([10])

e=d+a e=array([11,12,13])

f=10+a f=array([11,12,13])

They may obtained through attributes of the ndarray objects:

C.ndim x.ndim always equal to len(x.shape)

C.shape

C.size the number of elements: prod(x.shape)

[prod available in Python 3.8]

C.dtype the dtype of each scalar object

Creating arrays

np.zeros((3,2)) the arg must be a shape

return a zero matrix, dtype=float

np.ones((3,2)) return an all-one matrix, dtype=float

np.empty((3,2)) return an uninitialized matrix, dtype=float

All these functions may take the optional named parameter dtype=…

NumPy arrays from standard sequences “array like”:

x = np.array([2,3,1,0]) x = np.array([[1,2.0],[0,0],(1+1j,3.)])

note mix of tuple and lists, and types

x array([[1.+0.j, 2.+0.j], [0.+0.j, 0.+0.j], [1.+1.j, 3.+0.j]]) x.dtype dtype('complex128') type(x) <class 'numpy.ndarray'>

But careful: if the shape is not correct we will get “strange” results:

np.array(([1,2,3,4],[5,6])) array([list([1, 2, 3, 4]), list([5, 6])], dtype=object)

Arange :

np.arange(first,last,step) like range, but returns

a 1 - dim array, dtype=int last and step are optional Same as np.array(range(…)) np.arange(10,30,5) array([10,15,20,25])

We may use the reshape method to give a shape to a certain array:

np.arange(10,30,5).reshape((2,2)) array([[10, 15], [20, 25]])

v=np.arange(18).reshape((6,3)) array([[ 0, 1, 2], [ 3, 4, 5], [ 6, 7, 8], [ 9, 10, 11], [12, 13, 14], [15, 16, 17]]) v.reshape((3,3,2)) array([[[ 0, 1], [ 2, 3], [ 4, 5]], [[ 6, 7], [ 8, 9], [10, 11]], [[12, 13], [14, 15], [16, 17]]])

Of course the shape must match the size of the base array.

[reshape gives a view on the base array ; does not create a new array: more

later]

arange accepts float arguments, even a float step

The dtype of the created array object depends (more or less in the obvious way)

from the types of the arguments of arange

In the case of a float step, the size of the created object is non obvious, since it

depends on approximations:

from numpy import pi np.arange(pi, 3pi, pi) array([pi, 2pi]) np.arange(pi,3pi+10-15, pi) array([pi, 2pi 3pi]) np.arange(pi,3pi+10 ****- 16* , pi) array([pi, 2pi])

More useful is linspace which generates an uniformly spaced array:

np.linspace(0,2,9) 9 numbers from 0 to 9 (included)

array([0., 0.25, 0.5 , 0.75, 1., 1.25, 1.5 , 1.75, 2.])

c array([[ 6, 8], [10, 12], [14, 16]]) c1=c.sum(axis=1)

c1.shape we project along axis 1, so:

c array([[ 6, 9 ], [ 24 , 27]]) c2=c.sum(axis=2)

c2.shape we project along axis 2, so:

c array([[ 1, 5, 9 ], [ 13 , 17, 21]])

Some universal functions:

np.exp(a) for any element x, computes e^x

np.exp 2 (a) for any element x, computes 2^x

np.expm1(a) for any element x, computes e^x - 1

This function provides greater precision than exp(x) - 1 for small values of x.

No axis parameter may be given on these.

See:

https://docs.scipy.org/doc/numpy/reference/routines.math.html

x

Boolean operations as universal functions

For problems of too low level to be discussed here, the usual Boolean functions

(not, and, or) cannot be used as universal functions on arrays. Example:

Example:

x array([[21., 19., 18., 3.], [ 3., 4., 19., 21.]]) x> array([[ True, True, True, False], [False, False, True, True]]) not (x>4) Traceback (most recent call last): File "<pyshell#330>", line 1, in not (x>4) ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all() ~(x>4) array([[False, False, False, True],

[ True, True, False, False]])

Therefore some functions are redefined for this. Use:

~ for not

& for and

| for or

(x>4) and (x==4) Traceback (most recent call last): File "<pyshell#336>", line 1, in (x>4) and (x==4) ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all() (x>4) & (x==4) array([[False, False, False, False], [False, False, False, False]])

NumPy re-defines Booleans values (like it redefines integers “array scalars”).

np.True_ np.False_

Their “type”:

type(np.True_) <class 'numpy.bool_'>

Their dtype:

np.True_.dtype dtype('bool')

The reason for this seems to be the fact that Python does not provide any

'xxx' special methods corresponding to the 'and', 'or' and 'not' boolean operators

(contrary to other operations like +, *, or ==).

[PEP 335:

Axis

The j-axis of an array is the component of the array when you see its elements

as coordinates in a cartesian coordinate system:

I would start rows and columns at 0

Example:

For a 2-dim array:

axis 0: running vertically across rows (that is: columns)

axis 1: running horizontally across columns (that is: rows)

Some operations take an axis as a (often optional) parameter

Example:

v=np.arange(10).reshape(2,5) print('v: ', v) v: [[0 1 2 3 4] [5 6 7 8 9]] print('np.sum(v): ', np.sum(v)) np.sum(v): 45 print('np.sum(v, axis=0): ', np.sum(v, axis=0)) np.sum(v, axis=0): [ 5 7 9 11 13] print('np.sum(v, axis=1): ', np.sum(v, axis=1)) np.sum(v, axis=1): [10 35]

For sum, the default is axis None (along all axes)

The same function on 3-D:

We are summing along an axis, then the result will have as shape the original

shape without the dimension over which we are summing:

t=np.arange(12).reshape(2,2,3)

[[[ 0 1 2]

[ 3 4 5]]

[[ 6 7 8]

[ 9 10 11]]]

print('np.sum(t, axis=0): ') result of shape (2,3)

[[ 6 8 10]

[12 14 16]]

print('np.sum(t, axis=1): ') result of shape (2,3)

[[ 3 5 7]

[15 17 19]]

print('np.sum(t, axis=2): ') result of shape (2,2)

[[ 3 12]

[21 30]]