Unit 6: Introduction to NumPy - Subjective Questions
ECAP776 • Practice Questions with Detailed Answers
20 questions
Define a NumPy array. Explain how it differs from a Python list with respect to data type, memory usage, and supported operations.
A NumPy array, represented by numpy.ndarray, is a multidimensional collection of elements arranged in a fixed shape.
Differences:
- Data type: A NumPy array normally stores homogeneous elements of one
dtype, whereas a Python list can contain heterogeneous objects. - Memory: Arrays store elements compactly in a contiguous or strided memory block. Lists primarily store references to Python objects and therefore usually require more memory.
- Operations: NumPy supports vectorized element-wise operations, broadcasting, and numerical routines. Lists generally require loops or comprehensions for equivalent calculations.
- Dimensions: Arrays have explicit properties such as
shape,ndim, andsize; lists do not provide these numerical array attributes.
For example, np.array([1, 2, 3]) * 2 produces array([2, 4, 6]), while [1, 2, 3] * 2 repeats the list.
Compare the result of multiplication and addition operations on Python lists and NumPy arrays using suitable examples.
Multiplication:
- For a list,
[1, 2, 3] * 2gives[1, 2, 3, 1, 2, 3]because sequence repetition is performed. - For an array,
np.array([1, 2, 3]) * 2givesarray([2, 4, 6])because multiplication is element-wise.
Addition:
[1, 2] + [3, 4]gives[1, 2, 3, 4]because lists are concatenated.np.array([1, 2]) + np.array([3, 4])givesarray([4, 6])because corresponding elements are added.
Thus, Python list operators commonly perform sequence operations, whereas NumPy operators generally perform vectorized numerical operations.
Explain the meaning and importance of the NumPy array attributes ndim, shape, size, and dtype.
The main array attributes are:
ndim: Number of dimensions or axes in the array.shape: A tuple giving the length of the array along each axis.size: Total number of elements in the array; it equals the product of the shape values.dtype: Data type used to store each element, such asint64orfloat32.
For a = np.array([[1, 2, 3], [4, 5, 6]]):
a.ndimis2.a.shapeis(2, 3).a.sizeis6.a.dtypeis an integer type selected for the platform.
These attributes help verify whether an array has the required structure and storage type before numerical processing.
Why are NumPy arrays generally more suitable than Python lists for large numerical computations? Discuss vectorization and memory efficiency.
NumPy arrays are generally preferable for large numerical computations because:
- Compact storage: Elements of a homogeneous array are stored using a fixed number of bytes, while a list stores references to separate Python objects.
- Vectorization: NumPy applies an operation to an entire array without requiring an explicit Python loop.
- Compiled implementation: Many NumPy operations execute optimized compiled code, reducing interpreter overhead.
- Efficient traversal: Regular memory layout improves cache utilization.
- Numerical functionality: NumPy includes optimized aggregation, linear algebra, and statistical routines.
For example, a ** 2 squares every element of array a in one vectorized expression. A list usually requires [x ** 2 for x in values]. Vectorization makes code shorter and often significantly faster, although performance still depends on array size, data type, and operation.
Describe homogeneous storage and type promotion in NumPy arrays. What happens when integers and floating-point values are supplied together?
A standard NumPy array uses a single homogeneous data type for all its elements. When values of different compatible types are supplied, NumPy finds a common type capable of representing them through type promotion.
For example:
np.array([1, 2, 3])normally creates an integer array.np.array([1, 2.5, 3])normally creates a floating-point array, converting1and3to floating-point values.np.array([1, 2, 3], dtype=float)explicitly requests floating-point storage.
The selected type can be inspected with arr.dtype. Explicitly selecting a narrower type can reduce memory consumption, but it can also cause overflow or loss of precision if the values exceed that type's range.
Explain how np.zeros(), np.ones(), and np.full() create arrays. Give examples of creating arrays with shape .
These routines create arrays with a specified shape and initial value:
np.zeros((2, 3))creates a array filled with zeros.np.ones((2, 3))creates a array filled with ones.np.full((2, 3), 7)creates a array filled with7.
A type can be selected explicitly, such as np.zeros((2, 3), dtype=int).
Key distinction: zeros() and ones() use predefined fill values, whereas full() accepts a user-specified fill value. In all three routines, the shape is supplied as a tuple for a multidimensional array.
Describe np.empty(). How does it differ from np.zeros(), and why must its contents not be treated as initialized values?
np.empty(shape) allocates memory for an array but does not deliberately initialize each entry. Its visible contents depend on whatever bit patterns already exist in the allocated memory.
In contrast, np.zeros(shape) both allocates memory and initializes all elements to zero.
For example, np.empty((2, 2)) creates an array of the requested shape, but its displayed values are unpredictable and must not be interpreted as meaningful data. It is useful when every element will immediately be overwritten, because unnecessary initialization can be avoided.
Important: The array is structurally valid, but its element values should be considered uninitialized until explicitly assigned.
Explain the syntax and behavior of np.arange(). Determine the output of np.arange(2, 12, 3) and state an important limitation for floating-point steps.
np.arange(start, stop, step) creates evenly spaced values beginning at start and normally ending before the exclusive stop value.
For np.arange(2, 12, 3):
- Start at
2. - Repeatedly add
3. - Exclude values greater than or equal to
12.
Therefore, the output is array([2, 5, 8, 11]).
If only one argument is provided, it is treated as stop, so np.arange(4) produces [0, 1, 2, 3].
With floating-point steps, rounding errors can affect the number and exact values of elements. When an exact number of evenly spaced samples is required, np.linspace() is usually safer.
Compare np.arange() and np.linspace(). When should each routine be used?
np.arange(start, stop, step) is controlled by the distance between consecutive values. Its stop value is normally excluded. It is especially convenient for integer ranges.
np.linspace(start, stop, num) is controlled by the required number of samples. By default, both endpoints are included.
Examples:
np.arange(0, 10, 2)gives[0, 2, 4, 6, 8].np.linspace(0, 10, 6)gives[0., 2., 4., 6., 8., 10.].
Use arange() when the step size is fundamental. Use linspace() when the number of points and reliable endpoint handling are fundamental, especially with floating-point intervals.
Derive the spacing produced by np.linspace(a, b, n) when the endpoint is included. Then find the output of np.linspace(0, 1, 5).
When endpoint=True, which is the default, np.linspace(a, b, n) divides the closed interval from to into equal subintervals.
The spacing is:
For np.linspace(0, 1, 5):
The five values are therefore array([0.0, 0.25, 0.5, 0.75, 1.0]).
If endpoint=False, the stop value is excluded and the spacing calculation changes because the interval is divided into parts instead.
Explain the purpose of np.eye() and np.identity(). Create a identity matrix and describe a case where np.eye() is more flexible.
Both routines can create an identity matrix, whose main diagonal contains ones and whose other elements contain zeros.
A identity matrix can be created as:
np.eye(3)np.identity(3)
The result is conceptually:
np.eye() is more flexible because it can create rectangular arrays and can shift the diagonal using k. For example, np.eye(2, 3, k=1) creates a array with ones on the diagonal one position above the main diagonal. np.identity() always creates a square matrix.
Describe how a one-dimensional sequence created with an array creation routine can be converted into a multidimensional array using reshape(). State the necessary size condition.
reshape() changes the dimensions of an array without changing its element count or logical element order.
Example:
a = np.arange(12)creates 12 elements.b = a.reshape(3, 4)arranges them in 3 rows and 4 columns.
The necessary condition is:
Thus, a size-12 array can have shapes (3, 4), (4, 3), (2, 6), or (2, 2, 3), but not (5, 3). One dimension may be written as -1, as in a.reshape(3, -1), allowing NumPy to infer that dimension.
Explain how NumPy arrays are created from existing Python lists and tuples. Include examples of one-dimensional and two-dimensional input.
The np.array() function converts existing sequence data into an array.
One-dimensional examples:
np.array([10, 20, 30])converts a list.np.array((10, 20, 30))converts a tuple.
Two-dimensional example:
np.array([[1, 2, 3], [4, 5, 6]])converts a nested list into an array with shape(2, 3).
Nested sequences should have a regular rectangular structure for an ordinary multidimensional numeric array. A specific storage type can be requested with dtype, such as np.array([1, 2, 3], dtype=float). NumPy normally copies sequence data into its own homogeneous array storage.
Distinguish between np.array() and np.asarray() when converting existing data, especially when the input is already a NumPy array.
Both np.array() and np.asarray() convert compatible input into an ndarray, but their copying behavior differs.
np.array()creates an array and, by default, generally makes a copy when given an existing array.np.asarray()avoids a copy when the input is already a suitable array with the requested data type and representation.
Example:
b = np.array(a)normally creates independent array data.c = np.asarray(a)may returnaitself or an array sharing the same data.
asarray() is useful when a function needs array behavior without forcing an unnecessary copy. However, if independent storage is required, an explicit copy such as np.array(a, copy=True) or a.copy() should be used.
Describe the purpose of np.fromiter() and np.frombuffer() for creating arrays from existing data. Mention one important consideration for each routine.
-
np.fromiter(iterable, dtype, count=-1)creates a one-dimensional array by consuming values from an iterable. For example,np.fromiter((x * x for x in range(4)), dtype=int)produces[0, 1, 4, 9]. Thedtypemust be specified, and supplying an accuratecountcan improve allocation efficiency. -
np.frombuffer(buffer, dtype, count=-1, offset=0)interprets bytes from an object supporting the buffer protocol as a one-dimensional array. Itsdtype, byte order, and alignment must match the binary representation of the data.
A frombuffer() result may share memory with the original buffer, so changes and lifetime considerations can matter. It interprets existing bytes rather than parsing textual numbers.
Explain positive and negative indexing in a one-dimensional NumPy array. For a = np.array([10, 20, 30, 40, 50]), find a[1], a[-1], and a[-3].
Positive indices count from the beginning and start at 0. Negative indices count backward from the end, with -1 referring to the last element.
For a = np.array([10, 20, 30, 40, 50]):
a[1]is20, the second element.a[-1]is50, the last element.a[-3]is30, the third element from the end.
An index outside the valid range raises an IndexError. Indexing a one-dimensional array with a single integer normally returns a scalar value rather than another one-dimensional array.
Explain NumPy slicing using the general form start:stop:step. Determine a[1:7:2] and a[::-1] for a = np.arange(8).
The general slice start:stop:step selects elements beginning at start, advancing by step, and stopping before the exclusive stop index. Omitted values receive defaults based on the direction of the step.
For a = np.arange(8), the array is [0, 1, 2, 3, 4, 5, 6, 7].
a[1:7:2]selects indices1,3, and5, producingarray([1, 3, 5]).a[::-1]uses a step of-1, producingarray([7, 6, 5, 4, 3, 2, 1, 0]).
Like ordinary Python slicing, the stop index is excluded.
Describe indexing and slicing in a two-dimensional NumPy array. For a = np.arange(12).reshape(3, 4), determine a[1, 2], a[:, 1], and a[0:2, 2:4].
A two-dimensional array is indexed as array[row, column]. A colon selects all entries along an axis, and slices can be supplied independently for rows and columns.
The array is:
[[0, 1, 2, 3], [4, 5, 6, 7], [8, 9, 10, 11]]
Therefore:
a[1, 2]selects row1, column2, giving6.a[:, 1]selects column1from every row, givingarray([1, 5, 9]).a[0:2, 2:4]selects rows0and1and columns2and3, givingarray([[2, 3], [6, 7]]).
The result's dimensions depend on whether integer indices or slices are used.
Explain the difference between a basic slice view and an independent copy in NumPy. Demonstrate how modifying a slice can affect the original array.
Basic slicing normally returns a view of the original array rather than an independent copy. A view shares the underlying data, so modifying the view can modify the source array.
Example:
a = np.array([1, 2, 3, 4])b = a[1:3]b[0] = 99
After the assignment, a becomes array([1, 99, 3, 4]) because b shares data with a.
To obtain independent storage, use b = a[1:3].copy(). Changes to this copied array do not affect a.
This behavior makes slicing memory-efficient, but it can cause unintended side effects if data sharing is not recognized.
Compare basic slicing, integer array indexing, and Boolean indexing in NumPy. Use examples and explain whether the result usually shares data with the source.
Basic slicing uses expressions such as a[1:4]. It selects a regular range and normally returns a view that shares data with the source.
Integer array indexing supplies selected positions, such as a[[0, 2, 4]]. It can select nonconsecutive or repeated elements and normally returns a copy.
Boolean indexing uses a Boolean mask, such as a[a > 0], to select elements for which the condition is true. It also normally returns a copy.
For a = np.array([10, 20, 30, 40, 50]):
a[1:4]gives[20, 30, 40]through basic slicing.a[[0, 3]]gives[10, 40]through integer indexing.a[a >= 30]gives[30, 40, 50]through Boolean indexing.
Assignments through these indexing expressions can still update selected positions in the original when they appear on the left side of an assignment.
Define a NumPy array. Explain how it differs from a Python list with respect to data type, memory usage, and supported operations.
A NumPy array, represented by numpy.ndarray, is a multidimensional collection of elements arranged in a fixed shape.
Differences:
- Data type: A NumPy array normally stores homogeneous elements of one
dtype, whereas a Python list can contain heterogeneous objects. - Memory: Arrays store elements compactly in a contiguous or strided memory block. Lists primarily store references to Python objects and therefore usually require more memory.
- Operations: NumPy supports vectorized element-wise operations, broadcasting, and numerical routines. Lists generally require loops or comprehensions for equivalent calculations.
- Dimensions: Arrays have explicit properties such as
shape,ndim, andsize; lists do not provide these numerical array attributes.
For example, np.array([1, 2, 3]) * 2 produces array([2, 4, 6]), while [1, 2, 3] * 2 repeats the list.
Did this save you a night before the exam?
LPU Notes is free, and it stays free. Ads cover part of the server bill. The rest comes out of a student's own pocket: the domain, the storage, and keeping the site up through the weeks everyone needs it at once.
The payment button didn't load. An ad blocker or a filtered network is the usual reason. to try again.
Nothing here is ever locked, and nothing unlocks. Chip in only if it was worth it. What it pays for →