Python and NumPy: Element by Element Operations

Perquisites

For this guide we will use the Numeric Python library NumPy. We will need to import this as np.

Python

Element by Element Operations on Scalars

Lets first look at the addition of scalars. Let's now for the sake of conceptualisation prescribe the values we have to objects. If we have 3 pens at home and order 5 more pens then when our order arrives we will have:

3 pens + 5 pens = 8 pens

$\displaystyle \left[ {\text{3 pens}} \right]+\left[ {\text{5 pens}} \right]=\left[ {8\text{ pens}} \right]$

$\displaystyle \left[ 3 \right]+\left[ 5 \right]=\left[ 8 \right]$

$\displaystyle 3+5=8$

To write this in Python as a numeric numpy array we would use:

Python

8



However we would typically use variable names for instance, i for inventory, o for order and t for total. For each variable after it's assigned we can print its value and its datatype.

Python

i=
[3]
int32
o=
[5]
int32
t=
[8]
int32



It is also possible to use the function add with inputs i and o.

Python

t2=
[8]
int32



The items we illustrated are consumables. Assuming after order arrives we have 8 pens and use 6 of them up writing then after we put the 6 used up pens in the recycle bin we are left with:

8 pens – 6 pens = 2 pens

$\displaystyle \left[ {\text{8 pens}} \right]-\left[ {\text{6 pens}} \right]=\left[ {2\text{ pens}} \right]$

$\displaystyle \left[ 8 \right]-\left[ 6 \right]=\left[ 2 \right]$

$\displaystyle 8-6=8$

We can once again assign these to variables, for instance s for starting inventory, r for recycled inventory and e for ending inventory.

Python

s=
[8]
int32
r=
[6]
int32
e=
[2]
int32



The function subtract can also be used to subtract r from s:

Python

e2=
[2]
int32



Element by Element Operations on Vectors

Now let us conceptualise a more complicated example. Assume we have 3 pens and 2 pads at home, we then make a order for 5 more pens and 3 more pads.

Since pens and pads are separate objects we classify them as such. Let's essentially treat each item as a scalar:

3 pens + 5 pens = 8 pens

$\displaystyle \left[ {\text{3 pens}} \right]+\left[ {\text{5 pens}} \right]=\left[ {8\text{ pens}} \right]$

$\displaystyle \left[ 3 \right]+\left[ 5 \right]=\left[ 8 \right]$

$\displaystyle 3+5=8$

2 pads + 3 pads = 5 pads

If these are instead written as a vector we will have:

$\displaystyle \left[ {\begin{array}{*{20}{c}} {3\text{ pens}} \\ {2\text{ pads}} \end{array}} \right]+\left[ {\begin{array}{*{20}{c}} {\text{5 pens}} \\ {3\text{ pads}} \end{array}} \right]=\left[ {\begin{array}{*{20}{c}} {8\text{ pens}} \\ {5\text{ pads}} \end{array}} \right]$

$\displaystyle \left[ {\begin{array}{*{20}{c}} 3 \\ 2 \end{array}} \right]+\left[ {\begin{array}{*{20}{c}} 5 \\ 3 \end{array}} \right]=\left[ {\begin{array}{*{20}{c}} 8 \\ 5 \end{array}} \right]$

Once again we would typically use variable names for instance, iv for inventory, ov for order and tv for total, the v at the end distinguishing these variables as vectors compared to the earlier scalar variable created earlier. We use a comma , as a delimited to list each individual item (pens and pads). The square brackets [ ] are used to enclose the row.

Python

iv=
[3 2]
int32
ov=
[5 3]
int32
tv=
[8 5]
int32



Note if I instead had 2 pens on my desk and I ordered 3 pads then in vector notation I would have:

$\displaystyle \left[ {\begin{array}{*{20}{c}} {\text{2 pens}} \\ {0\text{ pads}} \end{array}} \right]+\left[ {\begin{array}{*{20}{c}} {\text{0 pens}} \\ {3\text{ pads}} \end{array}} \right]=\left[ {\begin{array}{*{20}{c}} {2\text{ pens}} \\ {3\text{ pads}} \end{array}} \right]$

With this notation bare in mind that pens and pads are separate objects meaning a pen cannot transform into a pad and a pad cannot transform into a pen!

$\displaystyle \left[ {\begin{array}{*{20}{c}} 2 \\ 0 \end{array}} \right]+\left[ {\begin{array}{*{20}{c}} 0 \\ 3 \end{array}} \right]=\left[ {\begin{array}{*{20}{c}} 2 \\ 3 \end{array}} \right]$

To write this in Python we would use:

Python

iv2=
[2 0]
int32
ov2=
[0 3]
int32
tv2=
[2 3]
int32



Note how we have to use zeros here to denote that we don't have a pad or pen in the first and second column vectors respectively. Element by Element operations will only work if the Arrays have the same amount of Elements.

If we started off with 8 pens and 5 pads and used up 6 pens and 3 pads then:

Written as a vector we will have:

$\displaystyle \left[ {\begin{array}{*{20}{c}} {\text{8 pens}} \\ {\text{5 pads}} \end{array}} \right]-\left[ {\begin{array}{*{20}{c}} {\text{6 pens}} \\ {3\text{ pads}} \end{array}} \right]=\left[ {\begin{array}{*{20}{c}} {2\text{ pens}} \\ {2\text{ pads}} \end{array}} \right]$

$\displaystyle \left[ {\begin{array}{*{20}{c}} 8 \\ 5 \end{array}} \right]-\left[ {\begin{array}{*{20}{c}} 6 \\ 3 \end{array}} \right]=\left[ {\begin{array}{*{20}{c}} 2 \\ 2 \end{array}} \right]$

To write this in Python we can use variables, for instance sv for starting inventory, rv for recycled inventory and ev for ending inventory, with the v distinguishing from the scalars created earlier and highlighting that these variables are vectors.

Python

sv=
[8 5]
int32
rv=
[6 3]
int32
ev=
[2 2]
int32



Element by Element Operations on Matrices

Okay so far, so good. Let's make things slightly more complicated now. Assume there are two neighbours, neighbour 1 lives in the red house and he has 3 pens and 2 pads, he makes an order for 5 pens and 3 pads and neighbour 2 lives in the green house and she has 2 pens and 2 pads, she makes an order for 7 pens and 5 pads. In this case after the order the man in the red house would have 8 pens and 5 pads whilst the woman would have 9 pens and 7 pads.

$\displaystyle \left[ {\begin{array}{*{20}{c}} {\text{3 pens}} & {2\text{ pens}} \\ {\text{2 pads}} & {\text{2 pads}} \end{array}} \right]+\left[ {\begin{array}{*{20}{c}} {\text{5 pens}} & {\text{7 pens}} \\ {\text{3 pads}} & {5\text{ pads}} \end{array}} \right]=\left[ {\begin{array}{*{20}{c}} {\text{8 pens}} & {\text{9 pens}} \\ {5\text{ pads}} & {7\text{ pads}} \end{array}} \right]$

$\displaystyle \left[ {\begin{array}{*{20}{c}} 3 & 2 \\ 2 & 2 \end{array}} \right]+\left[ {\begin{array}{*{20}{c}} 5 & 7 \\ 3 & 5 \end{array}} \right]=\left[ {\begin{array}{*{20}{c}} 8 & 9 \\ 5 & 7 \end{array}} \right]$

Once again we would typically use variable names for instance, im for inventory, om for order and tm for total, the m at the end distinguishing these variables as matrices. Recall that a matrix is seen as a list of rows where each row is itself a list.

HTML

For the problem above this gives:

Python

im=
[[3 2]
[2 2]]
int32
om=
[[5 7]
[3 5]]
int32
tm=
[[8 9]
[5 7]]
int32



Now let's assume the man living in the red house has 8 pens and 5 pads and consumes 6 pens and 3 pads and the woman living in the green house has 9 pens and 7 pads and consumes 8 pens and 4 pads. The man should therefore be left with 2 pens and 2 pads while the woman should be left with 1 pen and 3 pads.

$\displaystyle \left[ {\begin{array}{*{20}{c}} {\text{8 pens}} & {9\text{ pens}} \\ {\text{5 pads}} & {\text{7 pads}} \end{array}} \right]+\left[ {\begin{array}{*{20}{c}} {\text{6 pens}} & {\text{8 pens}} \\ {\text{3 pads}} & {4\text{ pads}} \end{array}} \right]=\left[ {\begin{array}{*{20}{c}} {\text{2 pens}} & {\text{1 pens}} \\ {2\text{ pads}} & {3\text{ pads}} \end{array}} \right]$

$\displaystyle \left[ {\begin{array}{*{20}{c}} 8 & 9 \\ 5 & 7 \end{array}} \right]+\left[ {\begin{array}{*{20}{c}} 6 & 8 \\ 3 & 4 \end{array}} \right]=\left[ {\begin{array}{*{20}{c}} 2 & 1 \\ 2 & 3 \end{array}} \right]$

$\displaystyle \left[ {\begin{array}{*{20}{c}} 8 \\ 5 \end{array}} \right]-\left[ {\begin{array}{*{20}{c}} 6 \\ 3 \end{array}} \right]=\left[ {\begin{array}{*{20}{c}} 2 \\ 2 \end{array}} \right]$

To write this in Python we can use variables, for instance sm for starting inventory, rm for recycled inventory and em for ending inventory, with the m denotating these variables are matrices:

Python

sm=
[[8 9]
[5 7]]
int32
rm=
[[6 8]
[3 4]]
int32
em=
[[2 1]
[2 3]]
int32



Element by Element Operations on Matrices (Special Case)

In general the dimensions of the matrices undergoing element by element operations such as addition and subtraction have to match however there are some special cases where one can add a scalar to a matrix or a vector which matches one of the dimensions of the a matrix.

If one adds a scalar to a matrix, the scalar is automatically adjusted to take the dimensions of matrices. i.e. the addition of 2 seems 2 of each item for each person in the order.

Python

im=
[[3 2]
[2 2]]
int32
os=
[2]
int32
tm2=
[[5 4]
[4 4]]
int32



When working with non-square matrices one can add a vector to the matrix and provided the dimensions of the vector match one of the dimensions of the matrix then it will automatically add the vector as either a row or column to every row and column of the matrix depending on the dimension that matches. When working with square matrices however, it is necessary to specify the vector as a row or column vector. For instance if we attempt to add the column vector to the matrix below:

We make a mistake and add the row vector (Python adds the vector as a row to a square matrix by default).

Python

im=
[[3 2]
[2 2]]
int32
ov=
[3 2]
int32
tm3=
[[6 4]
[5 4]]
int32



As we can see in the variable explorer, the dimensions of im are (2,2) meaning 2 rows by 2 columns whereas the dimensions of ov are just (2,). The preference it took was to match the number of rows and hence the vector was designated as a row vector when added to the matrix.

To rectify this we can convert the vector explicitly to either a row or column using the functions:

Python

Note to explicitly set a row (less commonly done as the default behaviour acts as a row) we must use double square brackets and to explicit set a column we only use a single square bracket.

Python

im=
[[3 2]
[2 2]]
int32
ovrow=
[[3 2]]
int32
ovcol=
[[3]
[2]]
int32
tm3=
[[6 4]
[5 4]]
int32
tm4=
[[6 5]
[4 4]]
int32



Note ovcol is (2,1) 2 rows and 1 column and ovrow is (1,2) 1 row by 2 columns.

Advertisements

This site uses Akismet to reduce spam. Learn how your comment data is processed.