Quick Notes on NumPy (Part-2/2)

Snehit Vaddi
5 min readOct 14, 2023

--

Welcome to the second part of our tutorial on NumPy. We will be covering some advanced but essential topics under the programming language. In the first part, we introduced our readers to NumPy and its basic operations like creating arrays, slicing, reshaping, and generating random numbers.

Btw, if you are looking for a Personal or Academic project, ping me @ v.snehith999@gmail.com I have a bunch to guide you.

Section -1: In this section, we will learn about:

  • Implementing Universal Functions (Ufuncs)
  • Arithmetic Functions
  • Trigonometric and Inverse Trigonometric Functions
  • Exponents and Logarithms
  • Implementing Advanced Ufuncs

Introduction to Universal Functions (Ufuncs).

Ufuncs in NumPy is simply mathematical functions. These functions include standard arithmetic operations, trigonometric functions, statistical functions, etc.

Ufuncs are used to vectorize operations and thereby remove slow Python loops.

Arithmetic Functions :

NumPy’s Arithmetic Ufuncs is quite similar to Python’s native arithmetic operations and hence operations like standard addition, subtraction, multiplication, and division can all be easily used:

Each of these arithmetic operations has a specific NumPy wrapper. Some of the wrappers are:

+ np.add
- np.subtract
- np.negative
* np.multiply
/ np.divide
// np.floor_divide
** np.power
% np.modPython Operators VS NumPy wrappers

Built-in NumPy wrappers for arithmetic operations:

Trigonometric functions:

NumPy provides many trigonometric functions and some of them are most useful for data scientists, like sin, cos, tan. These trigonometric functions work on radians. Hence, it is important to convert angles into radians. This is done by multiplying the value by pi/180.

Note: An array of degrees can be converted into radians by NumPy function np.deg2rad([angles])

Here, np.linspace() function generates N equally separated numbers between the specified start and end. np.pi is equal to 3.14159… radians which in turn is equal to 180 degrees.

Inverse Trigonometric Functions:

NumPy also provides various Inverse trigonometric functions. Unlike trigonometric functions, these functions take trigonometric values and return radians.

Exponents and Logarithms:

Another extremely useful operation available in NumPy Ufuncs is exponents.

In fact, logarithms are inverse of exponentials. The np.log function is used to find the natural logarithm. It provides two options to compute logarithms, either for base-2 or base-10.

Advances Ufuncs:

NumPy also provides some interesting aggregates that can be computed directly from the object. Eg. reduce and accumulate ufuncs.

Reduce on np.add ufuncs returns the sum of all elements in the array. Similarly, reduce on np.multiply ufuncs returns the product of all elements in the array.

Similar to reduce, if one would like to store all intermediate results of the computation, one can use accumulate in ufuncs.

Multidimensional Aggregation functions:

Now, let’s move to the various aggregation functions that are provided by NumPy. The aggregation functions operate on unidimensional and multi-dimensional functions. These functions are designed to deal with null and uncertain values. Some of the multidimensional aggregation functions are:

Section -2: In the next section of the blog, we will learn some other interesting topics related to NumPy. Let’s start with the following:

  • Broadcasting
  • Rules of Broadcasting
  • Examples of Broadcasting

Broadcasting:

In simple terms. Broadcasting is simply a set of rules for performing binary Ufuncs. The term Broadcasting refers to how NumPy treats arrays with different dimensions during arithmetic operations which leads to certain constraints.

Broadcasting is an extremely useful feature of ufuncs to operate between arrays of different sizes and shapes. Let’s look at a simple example to understand it better:

Rules of Broadcasting:

Broadcasting in NumPy follows a strict set of rules to determine the interaction between the two arrays:

  • Rule 1: If the two arrays differ in their number of dimensions, the shape of the one with fewer dimensions is padded with ones on its leading (left) side.
  • Rule 2: If the shape of the two arrays does not match in any dimension, the array with a shape equal to 1 in that dimension is stretched to match the other shape.
  • Rule 3: If in any dimension, the sizes disagree and neither is equal to 1, an error is raised.

Note: Any NumPy array which undergoes any arithmetic operations should follow these 3 Broadcasting rules.

Broadcasting Example 1:

Let’s consider adding a two-dimensional array to a one-dimensional array:

The shape of the arrays is as follows:

  • M.shape = (2, 3)
  • a.shape = (3,)

If we look at rule 1, it is clear that array a has fewer dimensions, so we pad it on the left with ones:

  • M.shape -> (2, 3)
  • a.shape -> (1, 3)

Using rule 2, we now see that the first dimension disagrees, so this dimension is stretched to match:

  • M.shape -> (2, 3)
  • a.shape -> (2, 3)

Finally, the shapes match and it is clear that the final shape will be (2, 3):

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

Broadcasting Example 2:

Now let’s take a look at an example in which the two arrays are not compatible:

The shape of the arrays is as follows:

  • M.shape -> (3, 2)
  • a.shape -> (3, )

Again, rule 1 tells us that we must pad the shape of a with ones:

  • M.shape -> (3, 2)
  • a.shape -> (1, 3)

By rule 2, the first dimension of a is stretched to match M.

  • M.shape -> (3, 2)
  • a.shape -> (3, 3)

In the end, we see that according to rule 3, the final shapes do not match. So, these two arrays are incompatible for attempting any operations.

Import Jovian and Commit:

Conclusion:

With this, we come to the end of PArt 2 of our Basics of NumPy series. We have managed to cover many topics, including sequencing, indexing, random numbers, reshaping, Ufuncs, and Broadcasting. We sincerely hope that you have learned not just the basics but have got a good understanding of the intermediate level of NumPy module as well. If you have any questions for us, please do get in touch.

References:

Complete Jupyter Notebook: https://jovian.ml/v-snehith999/numpy-basics-part-2

Basics of NumPy — Part 1: https://hub.jovian.ml/?p=603&preview=true

Practice NumPy functions: https://nbviewer.jupyter.org/github/rougier/numpy-100/blob/master/100_Numpy_exercises.ipynb

https://jakevdp.github.io/PythonDataScienceHandbook/02.05-computation-on-arrays-broadcasting.html

👋 About me:

Snehit Vaddi here!

Pursuing Masters in CS at University of Florida. I’m a ML enthusiast and Data freak. Teaching and learning go hand-in-hand for me, fueling my tech journey. Oh, and by the way, I’m on the lookout for some exciting Summer ’24 internships in the US. Let’s connect and collaborate!

🤝Linkedin: https://www.linkedin.com/in/snehitvaddi/

👩‍💻Github: https://github.com/snehitvaddi

--

--

Snehit Vaddi
Snehit Vaddi

Written by Snehit Vaddi

👨‍🎓I am a Machine Learning enthusiast. I teach machines how to see, listen, and learn.

No responses yet