Python for Data Science & Automation · Module 2: Numerical Computing with NumPy · Lesson 6 of 34

2.1 Introduction to NumPy ndarray

Introduction to NumPy ndarrays

NumPy (Numerical Python) is one of the most important Python libraries for numerical computing and forms a foundation for many Data Science, Machine Learning, and scientific computing workflows.

Its central data structure is the NumPy ndarray, short for N-dimensional array.

An ndarray stores values in a structured, multidimensional array and provides efficient operations for numerical computation.

In this lesson, you will learn:
  • What NumPy is
  • What an ndarray is
  • How an ndarray differs from a Python list
  • Why NumPy arrays are efficient for numerical computing
  • Creating a basic ndarray
  • One-dimensional and multidimensional arrays
  • Important ndarray attributes
  • Understanding dtype
  • Common NumPy data types
  • Checking and changing data types
  • Practical Data Science examples

1. What Is NumPy?

NumPy is an open-source Python library designed primarily for numerical and scientific computing.

It provides efficient data structures and operations for working with arrays, mathematical functions, statistics, linear algebra, and other numerical tasks.

Importing NumPy

import numpy as np

The alias np is the standard convention used in most Python Data Science code.

Remember:

np is an alias for the NumPy module. It is a convention, not a Python keyword.

2. What Is an ndarray?

An ndarray is NumPy's fundamental array object. The name stands for N-dimensional array.

Unlike a traditional Python list, an ndarray is designed specifically for efficient numerical operations.

Example

import numpy as np

numbers = np.array([10, 20, 30, 40])

print(numbers)

Output:

[10 20 30 40]

The object stored in numbers is a NumPy ndarray.

print(type(numbers))

Output:

<class 'numpy.ndarray'>

3. Python List vs NumPy ndarray

Both Python lists and NumPy arrays can store collections of values, but they are designed for different purposes.

Feature Python List NumPy ndarray
Purpose General-purpose collection. Numerical and scientific computing.
Data types Can contain mixed types. Usually stores a single dtype.
Dimensions Nested lists can represent dimensions. Native support for N-dimensional arrays.
Numerical operations Often require loops or comprehensions. Supports vectorized numerical operations.
Memory layout General Python object references. Designed for compact numerical storage.
Mathematical operations Not element-wise by default. Element-wise operations are built in.

4. Why Is NumPy Faster Than Python Lists?

NumPy can be significantly faster than Python lists for many numerical workloads because its arrays are specifically designed for numerical computation.

1. Homogeneous Data

NumPy arrays generally store elements using a consistent data type. This allows NumPy to use efficient memory layouts and numerical operations.

2. Contiguous Memory

NumPy can store array data in compact memory layouts, reducing overhead compared with a general-purpose Python list of objects.

3. Vectorized Operations

NumPy allows operations to be applied to entire arrays without explicitly writing a Python loop for every element.

4. Optimized Low-Level Operations

Many NumPy operations execute optimized compiled code internally, reducing the amount of work performed by the Python interpreter.

Example with a Python List

numbers = [10, 20, 30, 40]

result = []

for number in numbers:
    result.append(number * 2)

print(result)

Equivalent NumPy Operation

import numpy as np

numbers = np.array([10, 20, 30, 40])

result = numbers * 2

print(result)

Output:

[20 40 60 80]
Important:

It is not correct to say that NumPy is always faster than lists. NumPy's advantages are most significant for suitable numerical operations, especially on larger datasets.

5. Numerical Operations: List vs ndarray

One major difference appears when multiplying collections.

Python List

numbers = [1, 2, 3]

print(numbers * 2)

Output:

[1, 2, 3, 1, 2, 3]

List multiplication repeats the list.

NumPy ndarray

import numpy as np

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

print(numbers * 2)

Output:

[2 4 6]

NumPy performs the multiplication element by element.

6. Creating an ndarray

The most common way to create a NumPy array from existing Python data is np.array().

import numpy as np

numbers = np.array([10, 20, 30, 40])

print(numbers)

From a Tuple

data = np.array((10, 20, 30))

print(data)

From a Nested List

matrix = np.array([
    [1, 2, 3],
    [4, 5, 6]
])

print(matrix)

Output:

[[1 2 3]
 [4 5 6]]

7. Dimensions of an ndarray

NumPy arrays can have one or more dimensions.

Array Example Dimension
1D array [1, 2, 3] One dimension
2D array [[1, 2], [3, 4]] Rows and columns
3D array Multiple 2D arrays Three dimensions

1D Example

a = np.array([10, 20, 30])

print(a.ndim)

Output:

1

2D Example

b = np.array([
    [10, 20],
    [30, 40]
])

print(b.ndim)

Output:

2

8. Important ndarray Attributes

NumPy arrays provide several attributes that describe their structure and data.

Attribute Purpose
ndim Number of dimensions.
shape Size of the array along each dimension.
size Total number of elements.
dtype Data type of the array elements.
itemsize Number of bytes used by each element.
nbytes Total bytes consumed by the array elements.

9. ndim — Number of Dimensions

The ndim attribute returns the number of dimensions of an array.

import numpy as np

data = np.array([
    [10, 20, 30],
    [40, 50, 60]
])

print(data.ndim)

Output:

2

10. shape — Dimensions of the Array

The shape attribute returns a tuple describing the size along each dimension.

data = np.array([
    [10, 20, 30],
    [40, 50, 60]
])

print(data.shape)

Output:

(2, 3)

This means the array contains:

  • 2 rows
  • 3 columns
Exam Tip:

For a 2D array, shape is commonly written as (rows, columns).

11. size — Total Number of Elements

The size attribute returns the total number of elements in the array.

data = np.array([
    [10, 20, 30],
    [40, 50, 60]
])

print(data.size)

Output:

6

The relationship for this 2D array is:

2 rows × 3 columns = 6 elements

12. dtype — Data Type

The dtype attribute identifies the data type used to store the elements of a NumPy array.

numbers = np.array([10, 20, 30])

print(numbers.dtype)

Depending on the platform and NumPy version, an integer array may display a dtype such as:

int64

The exact default integer dtype can depend on the environment.

Floating-Point Example

values = np.array([10.5, 20.5, 30.5])

print(values.dtype)

A typical output is:

float64

13. Common NumPy Data Types

dtype Description Example
int32 32-bit signed integer. 10
int64 64-bit signed integer. 100000
float32 32-bit floating-point number. 10.5
float64 64-bit floating-point number. 3.14159
bool Boolean value. True
complex128 Complex number representation. 2 + 3j
str_ NumPy string type. "Python"

14. Specifying a dtype

You can explicitly specify the desired data type while creating an array.

numbers = np.array(
    [10, 20, 30],
    dtype=np.float64
)

print(numbers)
print(numbers.dtype)

Output:

[10. 20. 30.]
float64

Explicit dtypes can be useful when memory usage, numerical precision, or compatibility with another system matters.

15. Changing the dtype with astype()

The astype() method creates an array converted to a specified data type.

numbers = np.array([10, 20, 30])

decimal_numbers = numbers.astype(np.float64)

print(decimal_numbers)
print(decimal_numbers.dtype)

Output:

[10. 20. 30.]
float64
Important:

astype() generally returns a new array rather than changing the original array in place.

16. itemsize — Bytes per Element

The itemsize attribute returns the number of bytes occupied by each array element.

numbers = np.array(
    [10, 20, 30],
    dtype=np.int32
)

print(numbers.itemsize)

Output:

4

An int32 uses 4 bytes per element.

Similarly, int64 typically uses 8 bytes per element.

17. nbytes — Total Array Data Size

The nbytes attribute reports the total number of bytes occupied by the array elements.

numbers = np.array(
    [10, 20, 30],
    dtype=np.int32
)

print(numbers.nbytes)

Output:

12

Calculation:

3 elements × 4 bytes = 12 bytes

18. Exam-Focused ndarray Attributes

import numpy as np

data = np.array([
    [10, 20, 30],
    [40, 50, 60]
])

print("ndim:", data.ndim)
print("shape:", data.shape)
print("size:", data.size)
print("dtype:", data.dtype)
print("itemsize:", data.itemsize)
print("nbytes:", data.nbytes)

These attributes provide a quick description of the structure and storage characteristics of an ndarray.

19. NumPy Arrays and Homogeneous Data

NumPy arrays are generally designed to contain elements of a common data type.

numbers = np.array([10, 20, 30])

print(numbers.dtype)

If values of different compatible types are supplied, NumPy may perform type promotion to a common dtype.

data = np.array([10, 20.5, 30])

print(data)
print(data.dtype)

The integers can be promoted to a floating-point representation so the array has a common dtype.

20. Boolean ndarrays

NumPy can create arrays containing Boolean values.

attendance = np.array([
    True,
    True,
    False,
    True
])

print(attendance)
print(attendance.dtype)

Boolean arrays are especially useful later for filtering and conditional selection.

21. String Data in NumPy Arrays

NumPy can also store strings.

names = np.array([
    "Alex",
    "Jordan",
    "Taylor"
])

print(names)
print(names.dtype)

NumPy determines an appropriate string dtype based on the supplied data.

Data Science Tip:

For rich tabular text processing, pandas is generally more convenient than raw NumPy arrays. NumPy is primarily optimized for numerical array computation.

22. Zero-Dimensional Array

NumPy can also represent a single scalar value as a zero-dimensional array.

value = np.array(42)

print(value)
print(value.ndim)
print(value.shape)

The array has zero dimensions and an empty shape tuple.

23. One-Dimensional Array

scores = np.array([
    78,
    85,
    92,
    88
])

print(scores.ndim)
print(scores.shape)
print(scores.size)

Typical output:

1
(4,)
4

24. Two-Dimensional Array

scores = np.array([
    [78, 85, 92],
    [88, 76, 95]
])

print(scores.ndim)
print(scores.shape)
print(scores.size)

Output:

2
(2, 3)
6

This represents 2 rows and 3 columns.

25. Understanding shape Visually

data = np.array([
    [10, 20, 30],
    [40, 50, 60],
    [70, 80, 90]
])

The structure can be visualized as:

       Column
        0   1   2

Row 0  10  20  30
Row 1  40  50  60
Row 2  70  80  90

Therefore:

data.shape
(3, 3)

There are 3 rows and 3 columns.

26. type() vs dtype

These two concepts are often confused.

data = np.array([10, 20, 30])

print(type(data))
print(data.dtype)
Expression What It Tells You
type(data) The Python object type, such as numpy.ndarray.
data.dtype The data type of the array elements.
Exam Tip:

type() describes the container object; dtype describes the type used for its elements.

27. Data Science Example — Student Scores

NumPy arrays are useful for storing numerical observations such as marks, measurements, ratings, and sensor readings.

import numpy as np

scores = np.array([
    78,
    85,
    92,
    88,
    95
])

print("Scores:", scores)
print("Dimensions:", scores.ndim)
print("Shape:", scores.shape)
print("Number of values:", scores.size)
print("Data type:", scores.dtype)

These attributes provide immediate information about the dataset before further analysis.

28. Data Science Example — Temperature Data

temperatures = np.array(
    [24.5, 25.2, 26.8, 27.1, 25.9],
    dtype=np.float32
)

print(temperatures)
print(temperatures.dtype)
print(temperatures.shape)
print(temperatures.nbytes)

Explicitly selecting float32 can reduce memory usage compared with float64 when the lower precision is sufficient for the application.

29. Understanding Memory Efficiency

NumPy arrays use a defined dtype and compact numerical storage. This can make them substantially more memory-efficient than general Python objects for large numerical datasets.

import numpy as np

data = np.array(
    [10, 20, 30, 40, 50],
    dtype=np.int32
)

print("Elements:", data.size)
print("Bytes per element:", data.itemsize)
print("Total bytes:", data.nbytes)

Here, each element occupies 4 bytes and five elements require 20 bytes for the array's element data.

Important:

nbytes describes the memory occupied by the array's element data. It does not represent every possible Python object or array-management overhead.

30. ndarray Inspection Checklist

When you receive an unfamiliar NumPy array, inspect it using:

print(data.ndim)
print(data.shape)
print(data.size)
print(data.dtype)
print(data.itemsize)
print(data.nbytes)

These attributes provide a quick structural and storage profile of the array.

31. NumPy Interview Questions

Q1. What is an ndarray?

View Answer

An ndarray is NumPy's fundamental N-dimensional array object, designed for efficient storage and computation over array data.

Q2. Why can NumPy arrays be faster than Python lists for numerical operations?

View Answer

NumPy arrays use efficient numerical storage, homogeneous dtypes, vectorized operations, and optimized low-level implementations for many numerical workloads.

Q3. What does ndarray.shape return?

View Answer

It returns a tuple describing the size of the array along each dimension. For a 2D array it is commonly (rows, columns).

Q4. What is the difference between size and shape?

View Answer

shape describes the dimensions of the array, whereas size gives the total number of elements.

Q5. What is dtype in NumPy?

View Answer

dtype specifies the data type used to represent the elements of a NumPy array.

Q6. What is itemsize?

View Answer

itemsize gives the number of bytes occupied by each array element.

Q7. What does nbytes represent?

View Answer

nbytes reports the total number of bytes used by the array's element data.

32. Examination Questions

Multiple Choice Questions

Q1. What is the main data structure provided by NumPy for multidimensional numerical data?

  1. List
  2. Dictionary
  3. ndarray
  4. Tuple

Answer: C — ndarray

Q2. Which attribute returns the number of dimensions?

  1. size
  2. ndim
  3. shape
  4. dimension

Answer: B — ndim

Q3. What is the shape of this array?

data = np.array([
    [1, 2, 3],
    [4, 5, 6]
])
  1. (3, 2)
  2. (2, 3)
  3. (6,)
  4. (2, 2)

Answer: B — (2, 3)

Q4. Which attribute gives the total number of elements?

  1. ndim
  2. shape
  3. size
  4. itemsize

Answer: C — size

Q5. Which attribute gives the data type of array elements?

  1. type
  2. dtype
  3. datatype
  4. kind

Answer: B — dtype

Short Answer Questions

  1. Define NumPy and state two applications of the library.
  2. What is an ndarray?
  3. State two reasons why NumPy can be more efficient than Python lists for numerical workloads.
  4. Differentiate between ndim, shape, and size.
  5. What is the purpose of the dtype attribute?
  6. What is the difference between itemsize and nbytes?
  7. Explain the difference between type(array) and array.dtype.

33. Practical Challenge

Build an ndarray Dataset Inspector

Create a Python program that accepts or creates a NumPy array and displays its structural information.

  1. Import NumPy using the standard np alias.
  2. Create a 2D array containing numerical data.
  3. Display the array.
  4. Display its ndim.
  5. Display its shape.
  6. Display its size.
  7. Display its dtype.
  8. Display its itemsize.
  9. Display its nbytes.
  10. Convert the array to another appropriate dtype using astype() and inspect the result.

34. ndarray Quick Reference

Task Syntax
Import NumPy import numpy as np
Create an array np.array([1, 2, 3])
Check object type type(arr)
Number of dimensions arr.ndim
Array shape arr.shape
Total elements arr.size
Element data type arr.dtype
Bytes per element arr.itemsize
Total element-data bytes arr.nbytes
Specify dtype np.array(data, dtype=np.float32)
Convert dtype arr.astype(np.float64)

35. Key Takeaways

  • NumPy is a major Python library for numerical and scientific computing.
  • The ndarray is NumPy's fundamental N-dimensional array structure.
  • NumPy is particularly effective for large-scale numerical operations.
  • NumPy supports vectorized operations, reducing the need for explicit Python loops in many numerical tasks.
  • NumPy arrays generally use a common dtype for their elements.
  • ndim gives the number of dimensions.
  • shape describes the size along each dimension.
  • size gives the total number of elements.
  • dtype identifies the element data type.
  • itemsize gives the bytes used by each element.
  • nbytes gives the total bytes occupied by the array's element data.
  • astype() can be used to create an array with a different dtype.
  • Understanding ndarray structure is essential before learning NumPy indexing, slicing, reshaping, broadcasting, and statistical operations.
Golden Rule:

Think of a NumPy ndarray as a structured numerical data container: inspect its shape, dimensions, size, and dtype before performing analysis.