Python’s Numeric and Mathematical Modules: A Technical Overview
From Basic Arithmetic to Scientific Computing: Python’s Numeric and Mathematical Capabilities

Welcome to the world of numeric and mathematical computing in Python! If you’re a data analyst, scientist, engineer, or anyone else who works with numbers and calculations, this article is for you.
One of the great things about Python is that it makes it easy to perform complex calculations and numerical operations, even if you don’t have a background in mathematics. With its comprehensive set of built-in functions and modules, you can perform all sorts of calculations and manipulations with ease. And if you need even more power and flexibility, you can use third-party libraries such as NumPy and SciPy, which are specifically designed for scientific computing and data analysis. With these tools, you can perform complex operations such as linear algebra, optimization, and signal processing.
In this article, I’m going to dive deeper into the numeric and mathematical computing in Python, and show you how it can be used to make your work more efficient and effective. So let’s get started!
Numeric Types and Operations
Let’s start with integers and floating-point numbers. Integers are whole numbers that can be positive, negative, or zero, and they are used to represent whole quantities. Floating-point numbers, on the other hand, are numbers with a decimal point and can represent fractional quantities.
When working with integers and floating-point numbers, you’ll often perform basic arithmetic operations such as addition, subtraction, multiplication, and division. Python makes it easy to perform these operations with its simple syntax. For example, you can add two integers together like this:
>>> 2 + 3
5
You can also convert between integer and floating-point numbers as needed. For example, you can convert an integer to a floating-point number like this:
>>> float(3)
3.0
In addition these, Python also supports bitwise operations. These operations allow you to manipulate individual bits in an integer, and they can be useful for tasks such as encoding and decoding binary data. Some common bitwise operations include bitwise AND, OR, XOR, and shifting.
Numeric and Mathematical Modules
Now, let’s take a closer look at some of the key modules available in Python. They provide a rich set of tools for performing a wide range of numeric and math operations, and they are essential for anyone who works in scientific computing, data analysis, or any other field that requires numerical and mathematical processing.
First,math
module. This module provides a range of basic mathematical functions, including trigonometric functions, logarithmic functions, and power and exponential functions. Whether you need to calculate the sine of an angle, find the natural logarithm of a number, or raise a number to a power, the math
module is a right fit. Let’s see an example below:
import math
# calculate the factorial of a number
n = 5
factorial = math.factorial(n)
print(f"The factorial of {n} is {factorial}")
# calculate the natural logarithm of a number
x = 10
logarithm = math.log(x)
print(f"The natural logarithm of {x} is {logarithm}")
# calculate the base-2 logarithm of a number
x = 16
logarithm_base_2 = math.log2(x)
print(f"The base-2 logarithm of {x} is {logarithm_base_2}")
# calculate the base-10 logarithm of a number
x = 1000
logarithm_base_10 = math.log10(x)
print(f"The base-10 logarithm of {x} is {logarithm_base_10}")
# calculate the square root of a number
x = 25
square_root = math.sqrt(x)
print(f"The square root of {x} is {square_root}")
# calculate the sine of an angle in radians
angle = math.pi / 6
sine = math.sin(angle)
print(f"The sine of {angle} radians is {sine}")
# calculate the cosine of an angle in radians
cosine = math.cos(angle)
print(f"The cosine of {angle} radians is {cosine}")
# calculate the tangent of an angle in radians
tangent = math.tan(angle)
print(f"The tangent of {angle} radians is {tangent}")
# calculate the hyperbolic sine of a number
x = 2
hyperbolic_sine = math.sinh(x)
print(f"The hyperbolic sine of {x} is {hyperbolic_sine}")
# calculate the hyperbolic cosine of a number
hyperbolic_cosine = math.cosh(x)
print(f"The hyperbolic cosine of {x} is {hyperbolic_cosine}")
# calculate the hyperbolic tangent of a number
x = 1
hyperbolic_tangent = math.tanh(x)
print(f"The hyperbolic tangent of {x} is {hyperbolic_tangent}")
Next,cmath
module, which provides support for complex number operations. This module includes functions for performing trigonometric and logarithmic operations with complex numbers, making it a valuable tool for anyone working with complex numbers. Let’s now check an example with cmath
module to see its capabilities.
import cmath
# Define a complex number using the real and imaginary parts
z = complex(3, 4)
# Print the real and imaginary parts of the complex number
print(f"Real part: {z.real}")
print(f"Imaginary part: {z.imag}")
# Compute the absolute value (magnitude) of the complex number
print(f"Magnitude: {abs(z)}")
# Compute the complex conjugate of the complex number
z_conj = z.conjugate()
print(f"Complex conjugate: {z_conj}")
# Compute the phase angle of the complex number
theta = cmath.phase(z)
print(f"Phase angle: {theta}")
# Convert the complex number to polar coordinates
r, phi = cmath.polar(z)
print(f"Polar coordinates: r = {r}, phi = {phi}")
# Compute the square root of the complex number
z_sqrt = cmath.sqrt(z)
print(f"Square root: {z_sqrt}")
# Compute the exponential of the complex number
z_exp = cmath.exp(z)
print(f"Exponential: {z_exp}")
# Compute the sine, cosine, and tangent of the complex number
z_sin = cmath.sin
For those who need precise control over decimal arithmetic, the decimal
module is the perfect solution.
from decimal import Decimal, getcontext
# Set the precision for all Decimal instances
getcontext().prec = 10
# Create a Decimal object from a float
a = Decimal('1.1')
# Perform arithmetic with Decimal objects
b = Decimal('2.2')
c = a + b
# Compare Decimal objects with floats
d = 3.3
e = float(c)
print(c == d)
print(e == d)
# Round Decimal objects to a specific number of decimal places
f = Decimal('4.4444')
g = f.quantize(Decimal('0.01'))
# Convert Decimal objects to strings and back
h = str(g)
i = Decimal(h)
# Format Decimal objects with a specific number of decimal places
j = Decimal('5.5555')
k = j.quantize(Decimal('0.001'))
l = format(k, '.2f')
# Print the results
print(a)
print(c)
print(g)
print(i)
print(l)
And finally, the fraction
module has support for fraction arithmetic. Here’s an example:
from fractions import Fraction
# Creating fractions
f1 = Fraction(1, 2)
f2 = Fraction(3, 4)
# Basic arithmetic
print(f1 + f2) # 5/4
print(f1 - f2) # -1/4
print(f1 * f2) # 3/8
print(f1 / f2) # 2/3
# Converting to float or int
print(float(f1)) # 0.5
print(int(f2)) # 0
# Simplifying fractions
f3 = Fraction(12, 24)
print(f3) # 1/2
f4 = Fraction(4, -6)
print(f4) # -2/3
# Comparing fractions
print(f1 == f2) # False
print(f1 != f2) # True
print(f1 < f2) # True
print(f1 > f2) # False
print(f1 <= f2) # True
print(f1 >= f2) # False
# Fraction properties
f5 = Fraction(4, 5)
print(f5.numerator) # 4
print(f5.denominator) # 5
print(f5.real) # 0.8
print(f5.imag) # 0
# Conversion to mixed numbers
f6 = Fraction(7, 3)
print(f6) # 7/3
print(f6.numerator) # 7
print(f6.denominator) # 3
print(f6.as_integer_ratio()) # (7, 3)
# Converting from decimal to fraction
f7 = Fraction.from_float(0.125)
print(f7) # 1/8
f8 = Fraction.from_decimal(0.5)
print(f8) # 1/2
f9 = Fraction.from_float(1.25)
print(f9) # 5/4
# Continued fractions
f10 = Fraction.from_float(0.3).limit_denominator(10)
print(f10) # 3/10
print(f10.limit_denominator(100)) # 27/90
In addition to these basic modules, Python includes powerful tools for scientific computing and data analysis, such as NumPy and Matplotlib. These modules allow you to perform complex operations with arrays and matrices, visualize data, and much more.
Scientific Computing with NumPy
Numpy is a module with a wealth of tools and capabilities for data analysis, scientific simulations, or any other type of numerical computing. Let’s dig into it. NumPy is a library for the Python that provides support for arrays and matrices. It’s the backbone of many scientific computing and data analysis tools in Python, and it’s known for its high performance and ease of use. With NumPy, you can perform complex numerical operations and computations with ease, and you can also interface with other libraries and tools to extend your capabilities even further.
At the heart of NumPy are arrays, which are multi-dimensional containers for homogeneous data. With NumPy, you can create arrays from lists or other arrays, and you can also generate arrays using built-in functions such as zeros(), ones(), and arange(). Once you have an array, you can manipulate it in a variety of ways, such as changing its shape, transposing it, or reshaping it. It provides a vast array of functions and operations that you can use to perform computations on arrays. From basic arithmetic operations such as addition and multiplication, to more advanced functions such as dot products and matrix operations. You can also use NumPy’s broadcasting capabilities to perform operations between arrays of different shapes, making it easy to perform complex computations with ease. Let’s see an example:
import numpy as np
# Create an array of 10 random numbers between 0 and 1
a = np.random.rand(10)
# Print the array
print(a)
# Reshape the array to a 2x5 matrix
b = a.reshape((2, 5))
# Print the matrix
print(b)
# Transpose the matrix
c = b.T
# Print the transposed matrix
print(c)
# Compute the mean of the matrix along the first axis
d = np.mean(b, axis=0)
# Print the mean
print(d)
# Compute the standard deviation of the matrix along the second axis
e = np.std(b, axis=1)
# Print the standard deviation
print(e)
# Create a second matrix
f = np.random.rand(2, 5)
# Concatenate the two matrices along the first axis
g = np.concatenate((b, f), axis=0)
# Print the concatenated matrix
print(g)
# Compute the dot product of the concatenated matrix with its transpose
h = np.dot(g, g.T)
# Print the dot product
print(h)
With NumPy, you can easily access and manipulate specific elements or slices of arrays using indexing and slicing. You can also reshape arrays to fit your needs, whether that’s changing their shape, transposing them, or adding new dimensions. Let me show you with a quick example:
import numpy as np
# Create a 2-dimensional array with shape (3, 4)
a = np.array([[1, 2, 3, 4],
[5, 6, 7, 8],
[9, 10, 11, 12]])
# Indexing an array
print(a[0, 0]) # 1
print(a[2, 3]) # 12
# Slicing an array
print(a[1, 1:3]) # [6, 7]
print(a[:, 2]) # [3, 7, 11]
# Reshaping an array
b = a.reshape((2, 6))
print(b)
# [[ 1 2 3 4 5 6]
# [ 7 8 9 10 11 12]]
NumPy’s broadcasting capabilities allow you to perform operations between arrays of different shapes, making it easy to perform complex computations with ease. You can also use vectorization to perform operations on arrays in parallel, which can greatly speed up your computations. Let’s take a look at the next example that has two example for broadcasting and vectorization computation:
import numpy as np
# Create two arrays
a = np.array([1, 2, 3])
b = np.array([10, 20, 30])
# Broadcasting
c = a * 2
d = a + 10
# Vectorization
e = a + b
f = np.dot(a, b)
# Print the results
print(c) # [2, 4, 6]
print(d) # [11, 12, 13]
print(e) # [11, 22, 33]
print(f) # 140
It also provides a suite of linear algebra functions and operations. You can perform operations such as matrix multiplication, inversion, and decomposition, and you can also solve systems of linear equations using NumPy’s linear algebra capabilities. Let’s see that in action. In the next example, there are matrix multiplication, calculating the determinant of a matrix, its inverse, and also finding its eigenvalues and eigenvectors.
import numpy as np
# Create two matrices
a = np.array([[1, 2], [3, 4]])
b = np.array([[5, 6], [7, 8]])
# Add the two matrices
c = a + b
# Multiply the two matrices
d = np.dot(a, b)
# Calculate the determinant of a matrix
e = np.linalg.det(a)
# Calculate the inverse of a matrix
f = np.linalg.inv(a)
# Calculate the eigenvalues and eigenvectors of a matrix
g, h = np.linalg.eig(a)
# Print the results
print(c)
print(d)
print(e)
print(f)
print(g)
print(h)
Interfacing with Other Numeric and Mathematical Tools
Here, I’m going to talk about two most popular scientific modules: SciPy and SymPy. I start with SciPy first. It’s a library that provides a wide range of functionality for scientific computing and data analysis in Python. One of its key strengths is its optimization and fitting capabilities, which allow you to perform complex optimization tasks, such as finding the minimum of a function or fitting a model to data.
Let’s show how we can use Scipy for optimization and curve fitting.
import numpy as np
from scipy.optimize import minimize
from scipy.optimize import curve_fit
import matplotlib.pyplot as plt
# Define a test function
def func(x, a, b, c):
return a * np.sin(b * x) + c
# Generate some test data
xdata = np.linspace(0, 10, 100)
ydata = func(xdata, 2.5, 1.3, 0.5) + 0.2 * np.random.normal(size=len(xdata))
# Define the objective function for optimization
def objective(params):
return np.sum((ydata - func(xdata, *params))**2)
# Use the Nelder-Mead algorithm to minimize the objective function
initial_guess = [1, 1, 1]
result = minimize(objective, initial_guess, method='Nelder-Mead')
# Print the optimized parameters and the fit function
print(result.x)
xfit = np.linspace(0, 10, 1000)
yfit = func(xfit, *result.x)
# Use curve_fit to fit the data to the test function
popt, pcov = curve_fit(func, xdata, ydata)
# Print the optimized parameters and the covariance matrix
print(popt)
print(pcov)
# Plot the data and the fits
plt.plot(xdata, ydata, 'bo', label='Data')
plt.plot(xfit, yfit, 'r-', label='Minimized Fit')
plt.plot(xdata, func(xdata, *popt), 'g-', label='Curve Fit')
plt.legend()
plt.show()
In this example, I first define a test function that takes three parameters and generates a sinusoidal curve. I then generate some test data by applying some random noise to the test function.
Then I define an objective function that takes a set of parameters and returns the sum of the squared differences between the test data and the function evaluated with those parameters. Then use the minimize
function from scipy.optimize
to minimize the objective function using the Nelder-Mead algorithm.
I then print the optimized parameters and generate a fit function using the optimized parameters. Ialso use the curve_fit
function from scipy.optimize
to fit the test data to the test function, and print the optimized parameters and covariance matrix.
Finally, you can plot the data, the minimized fit function, and the curve fit function using the matplotlib
library. The plot shows that both fits are able to closely approximate the test data, demonstrating the power of the scipy
library for optimization and fitting in scientific computing applications.
In addition to optimization, SciPy also provides powerful tools for numerical integration and differentiation. For example, you can use the integrate module to perform numerical integration of functions, and the differentiate module to calculate derivatives of functions. Let’s see an example:
import numpy as np
from scipy.integrate import quad
from scipy.misc import derivative
# Define a function to integrate
def f(x):
return np.sin(x)
# Use quad to integrate the function over a range
a, b = 0, np.pi
result, error = quad(f, a, b)
print("Integral of sin(x) from 0 to pi: {:.4f}".format(result))
# Define a function to differentiate
def g(x):
return x**3 + 2*x**2 + x + 1
# Use derivative to compute the derivative of the function
x0 = 1
order = 1
result = derivative(g, x0, dx=1e-6, n=order)
print("First derivative of x^3 + 2x^2 + x + 1 at x=1: {:.4f}".format(result))
In this example, I first define a function f(x)
to integrate using the quad
function from SciPy's integrate
module. Then I specify the integration range as (a, b)
and call quad(f, a, b)
to compute the definite integral of f(x)
over the range (a, b)
. The function returns two values, the estimated integral value and an estimate of the absolute error in the result.
Next, I define a function g(x)
to differentiate using the derivative
function from SciPy's misc
module. I then specify the point at which to compute the derivative as x0
, the order of the derivative as order
, and the step size as dx
. The derivative
function returns the estimated derivative value.
SciPy is also a great tool for signal processing, offering functions for filtering, processing, and transforming signals. Whether you’re working with audio, image, or other types of signals, SciPy has the tools you need to get the job done. Let me also demonstrate that with an example:
import numpy as np
from scipy import signal
import matplotlib.pyplot as plt
# Generate a test signal
t = np.linspace(0, 10, 500)
x = np.sin(2 * np.pi * 5 * t) + np.sin(2 * np.pi * 20 * t)
# Plot the test signal
plt.plot(t, x)
plt.xlabel('Time (s)')
plt.ylabel('Amplitude')
plt.title('Original Signal')
plt.show()
# Apply a bandpass filter to the signal
fs = 50 # sampling frequency
nyq = 0.5 * fs # Nyquist frequency
f1 = 8 # lower cutoff frequency
f2 = 12 # upper cutoff frequency
Wn = [f1 / nyq, f2 / nyq] # critical frequencies as fractions of the Nyquist frequency
b, a = signal.butter(4, Wn, btype='band')
y = signal.filtfilt(b, a, x)
# Plot the filtered signal
plt.plot(t, y)
plt.xlabel('Time (s)')
plt.ylabel('Amplitude')
plt.title('Filtered Signal')
plt.show()
# Compute the spectrogram of the signal
f, t, Sxx = signal.spectrogram(y, fs=fs, nperseg=50)
plt.pcolormesh(t, f, np.log10(Sxx))
plt.ylabel('Frequency (Hz)')
plt.xlabel('Time (s)')
plt.title('Spectrogram')
plt.show()
In this example, I start by generating a test signal consisting of two sine waves at 5 Hz and 20 Hz. Then I plot the original signal using Matplotlib.
Next, I use the signal.butter
function to design a bandpass filter with a passband between 8 Hz and 12 Hz and apply the filter to the original signal using the signal.filtfilt
function, which performs zero-phase filtering to avoid phase distortion. Then I plot the filtered signal using Matplotlib.
Finally, I compute the spectrogram of the filtered signal using the signal.spectrogram
function, which computes the short-time Fourier transform of the signal. I then plot the spectrogram using Matplotlib.
Now, let’s talk about SymPy. SymPy is a library for symbolic mathematics in Python. It allows you to perform complex algebraic manipulations, and it provides a wide range of functionality for working with symbolic expressions and equations.
One of the key strengths of SymPy is its support for calculus and differential equations. Whether you’re solving a simple differential equation or working with more complex systems, SymPy has the tools you need to get the job done. Let’s see all of these in action:
import sympy
# Define some symbolic variables
x, y, z = sympy.symbols('x y z')
# Define some symbolic expressions
f = x**2 + 2*x + 1
g = x**3 + y**2 + z
# Take the derivative of an expression
dfdx = sympy.diff(f, x)
print(f"The derivative of {f} with respect to x is {dfdx}")
# Evaluate an expression at a point
f_value = f.subs(x, 2)
print(f"The value of {f} at x=2 is {f_value}")
# Expand an expression
h = (x + y)**2
expanded_h = sympy.expand(h)
print(f"The expansion of {h} is {expanded_h}")
# Factor an expression
factored_h = sympy.factor(expanded_h)
print(f"The factorization of {expanded_h} is {factored_h}")
# Solve an equation
solution = sympy.solve(f - 1, x)
print(f"The solution to {f} = 1 is {solution}")
# Simplify an expression
simplified_g = sympy.simplify(g)
print(f"The simplified expression for {g} is {simplified_g}")
The output is:
The derivative of x**2 + 2*x + 1 with respect to x is 2*x + 2
The value of x**2 + 2*x + 1 at x=2 is 9
The expansion of (x + y)**2 is x**2 + 2*x*y + y**2
The factorization of x**2 + 2*x*y + y**2 is (x + y)**2
The solution to x**2 + 2*x + 1 = 1 is [-2, 0]
The simplified expression for x**3 + y**2 + z is x**3 + y**2 + z
In conclusion, SciPy and SymPy are two powerful tools that can greatly enhance your numeric and mathematical workflow in Python. Whether you’re working with optimization and fitting, numerical integration and differentiation, or symbolic mathematics and calculus, these libraries provide the functionality and power you need to get the job done.
Resources for learning more about Python
A Deep Dive into the Python Standard Library (link)
A Deep Dive into the os Library in Python: Functions, Features, and Best Practices (link)
Concurrent Execution in Python: From Fundamentals to Advanced Topics (link)
From Text Files to Databases: How to Persist Data in Python (link)
Deep Dive into Pyarrow: Understanding its Features and Benefits (link)
Python and the Internet Protocol Stack: A Technical Overview (link)
Python Cryptography 101: Understanding and Implementing Cryptographic Services (link)
Abstract Classes: A Key Concept in Python’s Object-Oriented Toolkit (link)
Unlocking the Potential of Python’s Advanced Data Types (link)
The Power of Static Methods in Python (link)
I hope you enjoyed reading this 🙂. If you’d like to support me as a writer consider signing up to become a Medium member. It’s just $5 a month and you get unlimited access to Medium 🙏 .
Before leaving this page, I appreciate if you follow me on Medium and Linkedin 👉
Also, if you are a medium writer yourself, you can join my Linkedin group. In that group, I share curated articles about data and technology. You can find it: Linkedin Group. Also, if you like to collaborate, please join me as a group admin.
Subscribe to DDIntel Here.
Visit our website here: https://www.datadriveninvestor.com
Join our network here: https://datadriveninvestor.com/collaborate