88 NumPy Interview Questions and Answers (2026)

Blog / 88 NumPy Interview Questions and Answers (2026)
NumPy

NumPy shows up in almost every numerical, data, and scientific-computing stack, and interviewers know it. As datasets get bigger and interview bars rise, they're testing real fluency—broadcasting, views vs. copies, the memory model—not whether you can call a function you Googled.

This guide has 88 questions with concise, interview-ready answers and code where it helps. It's built Junior to Mid to Senior, so you start with fundamentals and push into the deep memory and performance topics that separate strong candidates from the rest.

Q1.
What is NumPy, and what are its core advantages that make it a preferred library for numerical computing in Python?

Junior

NumPy (Numerical Python) is the foundational library for numerical computing in Python, providing a fast, memory-efficient N-dimensional array object (ndarray) plus a rich set of vectorized operations, linear algebra, and random number tools.

  • Core object: the ndarray: A homogeneous, fixed-size, N-dimensional grid stored in a contiguous memory block.

  • Key advantages:

    • Speed: operations run in optimized C loops rather than interpreted Python loops.

    • Memory efficiency: raw numeric values packed together, no per-element Python object overhead.

    • Vectorization: element-wise math without explicit loops via +, *, and universal functions.

    • Broadcasting: operate on arrays of different shapes without copying data.

  • Ecosystem foundation: Pandas, SciPy, scikit-learn, TensorFlow, and others build on the ndarray.

Q2.
What are the key differences between NumPy arrays and Python lists, particularly regarding homogeneity, memory efficiency, and performance?

Junior

NumPy arrays are homogeneous, contiguously stored numeric buffers, while Python lists are heterogeneous collections of pointers to objects: this makes arrays far more memory-efficient and much faster for numerical work.

  • Homogeneity:

    • Arrays hold one fixed dtype for all elements; lists can mix ints, strings, objects.

    • Uniform typing is what enables compact storage and typed C loops.

  • Memory efficiency:

    • An array stores raw values back-to-back (e.g. 8 bytes per float64).

    • A list stores pointers to full Python objects, each carrying type and refcount overhead.

  • Performance:

    • Array operations are vectorized in C; list operations require slow per-element Python iteration.

    • Arrays are typically 10x to 100x faster for large numeric computations.

  • Flexibility trade-off: Lists are dynamic and can hold anything; arrays are fixed-size and typed but purpose-built for math.

Q3.
What are the key features and advantages of NumPy?

Junior

NumPy's central feature is the ndarray combined with vectorized operations, broadcasting, and a broad library of numerical routines that together deliver fast, concise numerical code.

  • N-dimensional arrays: Efficient, typed containers for vectors, matrices, and higher-dimensional tensors.

  • Vectorization and ufuncs: Element-wise math (np.sqrt, np.exp) runs in C without Python loops.

  • Broadcasting: Combine differently shaped arrays without explicit replication or copies.

  • Rich numerical toolkit: Linear algebra (np.linalg), random sampling (np.random), FFT, and statistical reductions.

  • Interoperability: Zero-copy interfaces to C/Fortran and the whole scientific Python stack.

Q4.
How does NumPy achieve its performance advantages compared to standard Python lists?

Junior

NumPy is fast because it moves work out of the Python interpreter: data is stored in contiguous typed buffers and operations execute as compiled, vectorized C loops over that buffer.

  • Contiguous, typed storage: Raw values sit together in memory, giving cache locality and avoiding per-element object overhead.

  • Vectorized C execution: A single call like a + b loops in C, avoiding Python bytecode dispatch per element.

  • No boxing/unboxing: Values are used directly as machine numbers, not wrapped Python objects.

  • Optimized backends and SIMD: Linear algebra routes to BLAS/LAPACK, and compilers use vector instructions.

  • Caveat: Writing Python for loops over an array throws away these gains: stay vectorized.

Q5.
How does NumPy store data in memory, and why is this efficient compared to Python lists?

Junior

NumPy stores an array as one contiguous block of raw, same-typed values, described by shape, dtype, and strides. A Python list, by contrast, stores an array of pointers to separate heap objects, which is why NumPy is far leaner.

  • The data buffer: A single flat C array of values, e.g. 1000 float64 packed as 8000 contiguous bytes.

  • The metadata:

    • shape gives dimensions; strides give byte steps per axis so any element is a simple offset computation.

    • This lets slices and reshapes be views sharing the same buffer, no copy.

  • Why it beats a list:

    • A list holds pointers, and each element is a full Python object with type tag and refcount overhead.

    • Contiguous values give cache locality and enable SIMD/vectorized C loops; scattered objects do not.

Q6.
Describe the different data types supported by NumPy.

Junior

NumPy supports a rich set of fixed-size numeric and non-numeric types, all described by a dtype object, so each element occupies a known number of bytes.

  • Boolean: bool_: a single byte True/False.

  • Integer types:

    • Signed: int8, int16, int32, int64.

    • Unsigned: uint8 through uint64 (the number is the bit width).

  • Floating point: float16, float32, float64 (default float), and platform float128.

  • Complex: complex64 and complex128 (two floats for real/imaginary parts).

  • Strings and bytes: Fixed-width byte strings S and Unicode U (e.g. 'U10' holds 10 characters).

  • Datetime: datetime64 and timedelta64 with unit resolution (year, day, ns, etc.).

  • Object and structured:

    • object: stores arbitrary Python objects as pointers.

    • Structured/record dtypes: named fields with mixed types, like a lightweight table row.

Q7.
What is dtype in NumPy, and what is its purpose?

Junior

A dtype (data type) is a NumPy object that describes how each element of an array is interpreted: its kind, size in bytes, and byte order. It is the metadata that turns a raw block of memory into meaningful typed values.

  • What it describes:

    • The type kind (int, float, bool, etc.), the item size (itemsize in bytes), and endianness.

    • For structured dtypes, the named fields and their offsets.

  • Its purpose:

    • Lets NumPy compute element offsets and run typed C operations without inspecting each value.

    • Controls memory footprint and numeric range/precision.

  • How you set it: Pass dtype= at creation, or convert later with astype().

python

import numpy as np a = np.array([1, 2, 3], dtype=np.float32) print(a.dtype) # float32 print(a.itemsize) # 4 (bytes per element)

Q8.
How do you inspect the data type (dtype) of elements in a NumPy array, and what are some common dtypes?

Junior

You inspect an array's element type through its .dtype attribute, and related attributes tell you the byte size and item count; NumPy exposes a small set of dtypes you meet constantly.

  • How to inspect:

    • arr.dtype gives the dtype object (e.g. dtype('int64')).

    • arr.dtype.name gives a readable string; arr.itemsize gives bytes per element.

    • Test kinds with np.issubdtype(arr.dtype, np.integer).

  • Common dtypes:

    • int64 (default integer on most platforms) and int32.

    • float64 (default float) and float32.

    • bool_, complex128, and object.

python

a = np.array([1, 2, 3]) print(a.dtype) # int64 print(a.dtype.name) # 'int64' print(a.itemsize) # 8

Q9.
What are the main attributes of a NumPy ndarray (e.g., shape, ndim, size, dtype)?

Junior

An ndarray is a fixed-size, homogeneous N-dimensional container, and its metadata attributes describe its layout and element type without copying data.

  • shape: Tuple giving the size along each dimension, e.g. (3, 4) for 3 rows and 4 columns.

  • ndim: Number of dimensions (axes); equals len(arr.shape).

  • size: Total number of elements, the product of all shape entries.

  • dtype: The element type (e.g. int64, float64); homogeneous across the whole array.

  • itemsize and nbytes: Bytes per element and total bytes (itemsize * size), useful for memory profiling.

  • strides: Bytes to step in each dimension to reach the next element; reveals memory layout and how views work.

Q10.
How do you determine the shape and size of a NumPy array, and what do these attributes represent?

Junior

Use the shape and size attributes: shape tells you how the elements are arranged across axes, and size tells you how many elements there are in total.

  • arr.shape: A tuple where each entry is the length along one axis; its length is the number of dimensions.

  • arr.size: A single integer equal to the product of the shape entries (total elements).

  • Related helpers:

    • len(arr) gives only the first-axis length, not the total, so prefer size for element counts.

    • np.shape(arr) and np.size(arr) work on list-like inputs too.

python

a = np.zeros((3, 4)) a.shape # (3, 4) -> 3 rows, 4 cols a.ndim # 2 a.size # 12

Q11.
How can you programmatically determine if a NumPy array is empty or contains zero elements?

Junior

Check arr.size == 0: that is the reliable, unambiguous test for an array with zero elements regardless of its shape.

  • Prefer arr.size == 0: Works for any dimensionality, including shapes like (0, 5) that hold no elements but still have axes.

  • Avoid truthiness on the array: if arr: raises ValueError for multi-element arrays (ambiguous truth value), so it is not a safe emptiness test.

  • Distinguish "empty" from "all zeros": size == 0 means no elements; use np.all(arr == 0) or not np.any(arr) to test whether existing elements are zero.

Q12.
Describe different ways to create NumPy arrays (e.g., np.array, zeros, ones, arange, linspace), and when you might choose one over another.

Junior

NumPy offers constructors for different needs: wrap existing data with np.array, pre-allocate placeholder arrays with zeros/ones, and generate numeric ranges with arange or linspace.

  • np.array(seq): Converts existing Python lists/tuples into an array; use when you already have the values.

  • np.zeros(shape) / np.ones(shape): Pre-allocate an array of a known size to fill later, or as a starting accumulator.

  • np.empty(shape) and np.full(shape, v): empty allocates without initializing (fastest, values are garbage); full fills with a constant.

  • np.arange(start, stop, step): Like range with a step; use when you care about the step size (stop is exclusive).

  • np.linspace(start, stop, num): Fixed count of evenly spaced points; use when you care about how many points and want the endpoint included.

  • Choosing: Known data -> np.array; known size to fill -> zeros/ones; sequence by step -> arange; sequence by count -> linspace.

Q13.
How can you generate random numbers and arrays using NumPy?

Junior

Use a random Generator from np.random.default_rng() and call its methods to draw scalars or whole arrays from various distributions by passing a size argument.

  • Create a generator: rng = np.random.default_rng(seed) is the recommended modern entry point.

  • Uniform floats: rng.random(size) gives values in [0, 1); rng.uniform(low, high, size) for an arbitrary range.

  • Integers: rng.integers(low, high, size) for random integers.

  • Distributions: rng.normal(loc, scale, size) for Gaussian; many others (poisson, binomial).

  • Sampling and shuffling: rng.choice(a, size, replace, p) to sample; rng.shuffle(a) and rng.permutation(a) to reorder.

  • Shape control: size can be a tuple to produce multi-dimensional arrays in one call.

python

rng = np.random.default_rng(0) rng.random((2, 3)) # 2x3 floats in [0,1) rng.integers(1, 7, size=5) # 5 dice rolls rng.normal(0, 1, size=4) # standard normal

Q14.
What is the difference between np.arange, np.linspace, and np.logspace, and when would you use each?

Junior

All three build 1-D numeric sequences, but arange is defined by a step size, linspace by a fixed count of evenly spaced points, and logspace by evenly spaced points on a logarithmic scale.

  • np.arange(start, stop, step):

    • You specify the step; stop is exclusive.

    • With float steps, floating-point rounding can make the element count unpredictable, so prefer linspace for floats.

  • np.linspace(start, stop, num):

    • You specify how many points; stop is included by default (endpoint=True).

    • Best when you need an exact number of evenly spaced samples.

  • np.logspace(start, stop, num):

    • Returns points evenly spaced in log space: values are base ** linspace(start, stop, num) (default base=10).

    • Use for log-scaled axes or hyperparameter sweeps spanning orders of magnitude.

python

np.arange(0, 10, 2) # [0 2 4 6 8] np.linspace(0, 1, 5) # [0. 0.25 0.5 0.75 1. ] np.logspace(0, 3, 4) # [ 1. 10. 100. 1000.]

Q15.
What is the difference between np.zeros, np.ones, and np.empty, and why is np.empty faster?

Junior

All three allocate an array of a given shape and dtype, but they differ in initialization: np.zeros fills with 0, np.ones fills with 1, and np.empty leaves memory uninitialized (contains whatever garbage was already there).

  • np.zeros(shape): Allocates memory and writes 0 into every element.

  • np.ones(shape): Allocates memory and writes 1 into every element.

  • np.empty(shape): Allocates memory only, with no fill step, so contents are arbitrary leftover bytes.

  • Why np.empty is faster:

    • It skips the O(n) pass that writes an initial value to every element.

    • The speedup is only meaningful for large arrays you will fully overwrite anyway.

  • Caution: never read from an np.empty array before writing it, values are undefined.

Q16.
How can you reshape a NumPy array, and what is the conceptual process and constraints like total number of elements?

Junior

Reshaping reinterprets the same data under a new shape using .reshape(): the memory buffer is unchanged, only the metadata describing dimensions and strides changes. The one hard constraint is that the total number of elements must stay the same.

  • Element-count constraint: The product of the new shape must equal the product of the old shape (e.g. a 12-element array can become (3,4) or (2,6) but not (5,3)).

  • Using -1 to infer a dimension: Pass -1 for one axis and NumPy computes it: arr.reshape(3, -1).

  • View vs copy:

    • reshape() returns a view when possible (no data copied), sharing memory with the original.

    • If the layout can't be expressed with strides (e.g. certain non-contiguous cases), it silently returns a copy.

  • Order matters: Default order='C' fills row-major; order='F' is column-major, affecting how elements map into the new shape.

python

a = np.arange(12) # shape (12,) b = a.reshape(3, 4) # view, same data c = a.reshape(2, -1) # -1 inferred as 6 -> (2, 6)

Q17.
How would you flatten a multi-dimensional array in NumPy?

Junior

Flattening collapses a multi-dimensional array into 1-D. The main options are .ravel(), .flatten(), and .reshape(-1), differing mainly in whether they return a view or a copy.

  • arr.ravel(): Returns a view when possible (no copy), so it's memory-cheap.

  • arr.flatten(): Always returns an independent copy, safe to modify without touching the original.

  • arr.reshape(-1): Equivalent to ravel in behavior: view when the layout allows.

  • Order parameter: order='C' (default) reads row-major; order='F' reads column-major.

Q18.
How do you transpose a matrix in NumPy using .T or np.transpose()?

Junior

Transposing swaps an array's axes; for a 2-D matrix it turns rows into columns. Both .T and np.transpose() return a view that reinterprets the same data via reordered strides, so no data is copied.

  • .T attribute: Shorthand for a full reversal of axes; ideal for 2-D matrices.

  • np.transpose(arr, axes): Lets you specify an explicit axis permutation for higher-dimensional arrays.

  • It's a view:

    • The result shares memory; modifying it changes the original.

    • The result is often non-contiguous; use np.ascontiguousarray() if a contiguous copy is needed.

  • Note: transpose is a no-op on 1-D arrays (shape unchanged).

python

a = np.arange(6).reshape(2, 3) a.T # shape (3, 2) np.transpose(a) # same result x = np.arange(24).reshape(2, 3, 4) np.transpose(x, (1, 0, 2)) # swap first two axes -> (3, 2, 4)

Q19.
What is the difference between indexing and slicing in NumPy?

Junior

Indexing selects individual elements at specific positions, while slicing selects a range (subarray) using start:stop:step: in NumPy, basic slices return views whereas single-element indexing returns a scalar.

  • Indexing:

    • a[2] or a[1, 3] pulls out a single element (a scalar) by position.

    • Negative indices count from the end: a[-1].

  • Slicing:

    • a[1:5] or a[::2] returns a subarray spanning a range.

    • Reduces one dimension per integer index but preserves dimensionality per slice.

    • Returns a view that shares memory with the source.

  • Key contrast: Indexing narrows to a point; slicing extracts a contiguous/strided block and stays connected to the original data.

Q20.
What is the purpose of the np.where() function?

Junior

np.where() is a vectorized conditional selector: it returns elements chosen from two sources depending on a boolean condition, or, in its single-argument form, the indices where a condition is True.

  • Three-argument form: element-wise choose:

    • np.where(cond, a, b) picks from a where cond is True, else from b; all three broadcast together.

    • Acts like a vectorized ternary, replacing an if/else loop.

  • One-argument form: find indices: np.where(cond) returns a tuple of index arrays (one per dimension) marking True positions.

  • Common uses: Clamping/replacing values (e.g. set negatives to 0), building masks, or locating matches.

python

a = np.array([-2, 3, -1, 5]) np.where(a < 0, 0, a) # array([0, 3, 0, 5]) np.where(a < 0) # (array([0, 2]),) -> indices

Q21.
How do np.any and np.all work, and how are they used with boolean arrays?

Junior

np.any and np.all reduce a boolean array to a single truth value (or per-axis values): np.any tests whether at least one element is True, np.all whether every element is True.

  • How they evaluate:

    • np.any is a logical OR across elements; np.all is a logical AND.

    • Non-zero/non-empty values count as True (works on numeric arrays too).

  • The axis argument: Without axis they reduce the whole array to one bool; with axis=0/1 they reduce along that dimension.

  • Typical usage:

    • Combine with a comparison to ask questions of the data: np.any(a < 0) ("are there any negatives?"), np.all(a > 0) ("are all positive?").

    • Avoids the ambiguous truth-value error you get from if array: on a multi-element array.

python

a = np.array([[1, -2], [3, 4]]) np.any(a < 0) # True np.all(a > 0) # False np.all(a > 0, axis=0) # array([ True, False])

Q22.
How do you perform element-wise arithmetic operations on NumPy arrays?

Junior

You perform element-wise arithmetic by applying standard operators directly to arrays: each operator maps to a ufunc that pairs up corresponding elements. Arrays should be shape-compatible (identical shapes, or broadcastable).

  • Use ordinary operators:

    • +, -, *, /, **, % all act element-by-element.

    • Equivalent ufuncs exist: np.add, np.subtract, np.multiply, np.divide.

  • Array-with-scalar: The scalar is broadcast to every element, e.g. a * 2.

  • In-place variants: +=, *= modify the array without allocating a new one (must be compatible dtype).

  • Shape rules: Same shape maps element-to-element; different shapes must satisfy broadcasting or raise a ValueError.

python

a = np.array([1, 2, 3]) b = np.array([10, 20, 30]) a + b # array([11, 22, 33]) a * b # array([10, 40, 90]) element-wise, NOT dot product a * 2 # array([2, 4, 6]) scalar broadcast

Q23.
Explain the axis argument in NumPy aggregations and operations. What do axis=0, axis=1, and axis=None mean, and how do they affect the result?

Junior

The axis argument selects which dimension an operation collapses (reduces) along. The rule: the axis you name is the one that disappears from the result. axis=0 reduces down the rows (per column), axis=1 reduces across the columns (per row), and axis=None reduces over the entire array to a scalar.

  • axis=0: Operates down each column (collapses the row dimension); for a (m,n) array the result has shape (n,).

  • axis=1: Operates across each row (collapses the column dimension); result shape (m,).

  • axis=None (default for many aggregations): Flattens everything and returns a single scalar.

  • Mnemonic and options:

    • "The named axis is consumed." Negative axes count from the end (axis=-1 is the last).

    • Pass keepdims=True to retain the reduced axis as length 1, which helps later broadcasting.

python

x = np.array([[1, 2, 3], [4, 5, 6]]) x.sum(axis=0) # [5, 7, 9] per column x.sum(axis=1) # [6, 15] per row x.sum() # 21 whole array (axis=None)

Q24.
Explain how to calculate common descriptive statistics like mean, median, standard deviation, and variance using NumPy, specifically addressing the axis parameter.

Junior

NumPy provides direct functions for descriptive statistics: np.mean, np.median, np.std, and np.var. Each accepts an axis argument that controls whether you get one number for the whole array or one per row/column.

  • The functions:

    • np.mean: arithmetic average.

    • np.median: middle value (robust to outliers).

    • np.std and np.var: spread and its square.

  • The axis parameter:

    • axis=None (default): statistic over all elements, returns a scalar.

    • axis=0: one value per column; axis=1: one value per row.

  • Key gotcha: sample vs population: np.std/np.var default to ddof=0 (population, divide by N). Use ddof=1 for the sample estimate (divide by N-1).

  • NaN-safe variants: np.nanmean, np.nanstd, etc. ignore NaN values.

python

x = np.array([[1, 2, 3], [4, 5, 6]]) np.mean(x) # 3.5 whole array np.mean(x, axis=0) # [2.5, 3.5, 4.5] per column np.median(x, axis=1) # [2., 5.] per row np.std(x) # population std (ddof=0) np.std(x, ddof=1) # sample std

Q25.
How do you calculate the cumulative sum or product of a NumPy array?

Junior

Use np.cumsum for a running total and np.cumprod for a running product. Unlike sum or prod, these return an array the same length as the input, holding every intermediate result, and they also accept an axis argument.

  • np.cumsum: Each element is the sum of all preceding elements plus itself.

  • np.cumprod: Each element is the product of all preceding elements times itself.

  • Axis behavior on 2D arrays:

    • No axis (default None): the array is flattened first, giving a 1D cumulative result.

    • axis=0 accumulates down columns; axis=1 accumulates across rows.

  • Related: They are the accumulate methods of np.add and np.multiply; NaN-safe versions are np.nancumsum/np.nancumprod.

python

a = np.array([1, 2, 3, 4]) np.cumsum(a) # [1, 3, 6, 10] np.cumprod(a) # [1, 2, 6, 24] m = np.array([[1, 2], [3, 4]]) np.cumsum(m, axis=0) # [[1, 2], [4, 6]] np.cumsum(m, axis=1) # [[1, 3], [3, 7]]

Q26.
What is the role of the axis parameter in NumPy's sorting functions?

Junior

The axis parameter tells a sort function which dimension to sort along, so each 1-D slice taken along that axis is sorted independently.

  • axis=-1 (default): Sorts along the last axis: for a 2-D array this sorts each row.

  • axis=0: Sorts down each column (across rows).

  • axis=None: Flattens the array first, then sorts the whole thing into 1-D.

  • Shape is preserved: Unlike aggregations, sorting along an axis keeps the array's shape; only the ordering within each slice changes.

python

a = np.array([[3, 1], [2, 4]]) np.sort(a, axis=1) # [[1,3],[2,4]] rows sorted np.sort(a, axis=0) # [[2,1],[3,4]] columns sorted

Q27.
What do np.argmin and np.argmax return, and how do they differ from np.min and np.max?

Junior

np.argmin and np.argmax return the index (position) of the smallest/largest element, whereas np.min and np.max return the value itself.

  • arg* return positions: Useful when you need to locate the extreme or index into another aligned array.

  • min/max return values: arr[arr.argmax()] == arr.max() always holds.

  • Ties: arg* return only the first occurrence of the extreme value.

  • With axis: On a flattened array the index is a single int; use np.unravel_index to convert it to multi-dimensional coordinates.

Q28.
What does np.clip do, and when would you reach for it?

Junior

np.clip limits (clamps) array values to a range: anything below the minimum becomes the minimum, anything above the maximum becomes the maximum, and values in between are unchanged.

  • Signature: np.clip(a, a_min, a_max); pass None for one bound to clip only from one side.

  • Vectorized and fast: Replaces manual masking like a[a < lo] = lo in a single call.

  • When to reach for it: Avoid divide-by-zero or log(0) by clamping to a small epsilon; keep pixel values in [0,255]; bound probabilities to [0,1]; cap outliers.

  • Bounds can broadcast: a_min / a_max may be arrays that broadcast against a for per-element limits.

Q29.
When can you add two NumPy arrays together, and what conditions enable broadcasting?

Junior

You can add two arrays whenever their shapes are broadcast-compatible: they are identical, or for each trailing dimension the sizes are equal or one of them is 1 (including a scalar).

  • Identical shapes: Straightforward element-wise addition; the common case.

  • Broadcast-compatible shapes: Compared right to left, each dimension pair must be equal or contain a 1; missing leading dims count as 1.

  • Enabling conditions: A scalar adds to any array; a (3,) row adds to a (5,3) matrix; a (5,1) column plus a (1,3) row makes a (5,3) result.

  • When it fails: A mismatch where neither dimension is 1 (e.g. (3,) + (4,)) raises a ValueError about non-broadcastable shapes.

Q30.
What is a NumPy ndarray and what makes it efficient?

Mid

An ndarray is NumPy's N-dimensional array: a single contiguous block of same-typed data plus lightweight metadata describing how to interpret that block. Its efficiency comes from storing raw values compactly and operating on them in compiled C.

  • What it is:

    • A homogeneous, fixed-size grid of elements all sharing one dtype.

    • Metadata includes shape, dtype, and strides (byte steps per axis).

  • Why it is efficient:

    • Contiguous memory gives cache-friendly access and no pointer chasing.

    • Strides let views (slices, reshapes, transposes) reinterpret the same buffer without copying.

    • Uniform typing lets NumPy run tight compiled loops instead of interpreting per element.

Q31.
Explain the trade-offs between using NumPy arrays and other Python data structures like lists and dictionaries for numerical computations.

Mid

For bulk numerical computation NumPy arrays win decisively on speed and memory, but lists and dictionaries remain better for heterogeneous, dynamic, or key-based data: choose based on data shape and access pattern.

  • NumPy arrays:

    • Pro: fast vectorized math, compact memory, broadcasting, rich numeric API.

    • Con: fixed type, fixed size (append/resize is expensive), overkill for tiny or mixed data.

  • Lists:

    • Pro: heterogeneous, dynamically resizable, cheap append.

    • Con: slow and memory-heavy for numeric loops (pointers to boxed objects).

  • Dictionaries:

    • Pro: O(1) key lookup, ideal for sparse or labeled/associative data.

    • Con: no vectorized arithmetic, high per-entry overhead, poor cache locality.

  • Rule of thumb: Dense homogeneous numbers, use arrays; growing/mixed sequences, use lists; keyed lookups, use dicts (or a labeled layer like Pandas).

Q32.
What are the advantages of NumPy over other numerical computing environments like Matlab/Octave for Python developers?

Mid

NumPy gives Python developers Matlab-like array computing while keeping the advantages of a general-purpose language, an open ecosystem, and free licensing.

  • General-purpose host language: Numerical code lives alongside web services, I/O, databases, and automation, not a math-only environment.

  • Open source and free: No per-seat license cost, unlike Matlab; easy to deploy anywhere.

  • Ecosystem depth: Integrates seamlessly with Pandas, SciPy, scikit-learn, and ML frameworks.

  • Explicit, readable semantics: 0-based indexing and clear broadcasting rules; arrays are references, so copies are explicit.

  • Trade-off to acknowledge: Matlab ships polished built-in toolboxes; in Python you assemble packages, but they are freely available.

Q33.
Explain the concept of data types in NumPy arrays. Why are NumPy arrays homogeneous, and what are the implications for performance and memory?

Mid

A NumPy array stores every element as the same fixed-size type described by its dtype, which is what makes arrays homogeneous. This uniformity lets NumPy pack values in one contiguous memory block and process them with fast, vectorized C loops.

  • Homogeneous by design: Every element has identical size and layout, so element N lives at a predictable byte offset (base + N * itemsize).

  • Memory efficiency: No per-element Python object overhead: a million int64 values take ~8 MB, versus a Python list of int objects that is many times larger.

  • Performance: Contiguous, typed data enables vectorized C loops, SIMD, and cache-friendly access with no boxing/unboxing.

  • Implications and trade-offs:

    • You must pick a dtype wide enough to avoid overflow or precision loss.

    • Mixing types forces promotion to a common dtype, or falls back to slow object arrays that lose these benefits.

Q34.
How do you handle arrays with different data types in NumPy given its homogeneous nature, and what is the exception with object dtype?

Mid

Because arrays are homogeneous, NumPy stores mixed inputs by promoting them to one common dtype; when no meaningful numeric common type exists, it falls back to object dtype, which can hold arbitrary Python objects at the cost of NumPy's speed advantages.

  • Default behavior: promotion: np.array([1, 2.5]) becomes all float64; np.array([1, 'a']) becomes a string dtype.

  • Structured dtypes for genuinely mixed columns: Define named fields (e.g. an int and a string per record) to keep each column typed within one array.

  • The object dtype escape hatch:

    • With dtype=object each slot is a pointer to a real Python object, so you can mix ints, strings, lists, anything.

    • Cost: you lose vectorized C loops and compact storage: operations run at Python speed.

  • Rule of thumb: For heterogeneous tabular data prefer pandas or structured arrays; reserve object dtype for truly irregular data.

Q35.
Explain the difference between np.copy() and np.asarray() when converting data types or creating arrays.

Mid

np.copy() always creates a new, independent array, whereas np.asarray() avoids copying when possible: it returns the input unchanged if it is already an array of the requested dtype.

  • np.copy():

    • Guarantees a fresh buffer; mutating the copy never affects the original.

    • Use when you need isolation from the source data.

  • np.asarray():

    • Returns the same object (no copy) if it is already an ndarray with a matching dtype; otherwise it converts.

    • Use to cheaply ensure something is an array at a function boundary.

  • Key implication:

    • After asarray the result may share memory with the input, so writes can propagate; after copy they never do.

    • For a dtype change, both convert: but asarray still skips the copy if the dtype already matches.

python

a = np.array([1, 2, 3]) b = np.asarray(a) # b is a (no copy) c = np.copy(a) # c is a new array print(b is a, c is a) # True False

Q36.
How does astype work for casting arrays, and what are the safe/same_kind/unsafe casting rules?

Mid

astype() returns a new array converted to a target dtype (copying by default), and its casting argument controls how strictly the conversion is validated, from fully safe to entirely unchecked.

  • How astype works:

    • arr.astype(np.float32) allocates a new array with the new dtype and copies converted values.

    • copy=False may skip the copy if the dtype already matches.

    • By default it uses casting='unsafe', so it will happily truncate floats to ints.

  • Casting rules (strict to loose):

    1. safe: only conversions that preserve all values (e.g. int32 -> float64).

    2. same_kind: safe casts plus casts within the same category (e.g. float64 -> float32).

    3. unsafe: any conversion allowed, even lossy ones like float -> int.

  • Practical tip: Pass casting='safe' to force a TypeError on risky conversions instead of silent data loss; verify with np.can_cast().

python

a = np.array([1.7, 2.9]) a.astype(np.int32) # array([1, 2]) - truncates (unsafe default) a.astype(np.int32, casting='safe') # raises TypeError

Q37.
What is a 0-dimensional array in NumPy, and how do you extract a Python scalar from an array using .item() or .tolist()?

Mid

A 0-dimensional array is a scalar wrapped in an ndarray: it has ndim == 0 and an empty shape (), and you extract a native Python scalar from it with .item().

  • 0-d array vs scalar: np.array(5) has shape () and is still an array with a dtype, not a plain Python int.

  • .item(): Returns a single native Python scalar (int, float, etc.); on a larger array it requires exactly one element or an index.

  • .tolist(): Converts any array to nested Python lists/scalars; on a 0-d array it returns the bare scalar too.

  • Why it matters: Native scalars serialize cleanly (JSON) and avoid surprising NumPy type behavior downstream.

python

x = np.array(3.14) x.ndim # 0 x.shape # () x.item() # 3.14 (Python float) type(x.item()) # <class 'float'>

Q38.
What is the purpose of np.random.seed() or the modern default_rng with a seed, and why is it important for reproducibility?

Mid

Seeding fixes the starting state of the pseudo-random generator so the same code produces the same "random" sequence every run, which is essential for reproducible experiments, tests, and debugging.

  • Pseudo-random, not truly random: Numbers come from a deterministic algorithm; the seed selects which deterministic sequence you get.

  • Legacy np.random.seed(): Sets a single global state used by np.random.* functions; convenient but shared across the whole program, so it is easy to disturb.

  • Modern default_rng(seed):

    • Creates an independent Generator object with its own state, so different parts of a program don't interfere.

    • Preferred in new code: better statistical properties and explicit, isolated state.

  • Why reproducibility matters: Lets others rerun your results, makes bugs deterministic, and keeps ML train/test splits and initializations consistent.

python

rng = np.random.default_rng(42) rng.random(3) # same 3 numbers every run with seed 42

Q39.
Explain the difference between np.vstack(), np.hstack(), and np.concatenate() when combining multiple arrays.

Mid

All three join arrays, but np.concatenate() is the general tool that joins along an existing axis, while np.vstack() and np.hstack() are convenience wrappers that stack vertically (rows) and horizontally (columns).

  • np.concatenate((a, b), axis=...):

    • Joins along a chosen existing axis; arrays must match on all other axes.

    • Never adds a new dimension.

  • np.vstack():

    • Stacks along axis 0 (rows on top of each other), roughly concatenate on axis=0.

    • Promotes 1-D inputs to rows first, so 1-D arrays become a 2-D result.

  • np.hstack(): Stacks along axis 1 for 2-D (columns side by side); for 1-D it joins along axis 0.

  • Rule of thumb: Use concatenate for explicit axis control; use vstack/hstack for readable common cases.

Q40.
Explain the different methods for combining (concatenate, stack, vstack, hstack) and splitting (split, vsplit, hsplit) NumPy arrays.

Mid

Combining functions join arrays into one; splitting functions divide one array into several. The key distinction is whether an operation works along an existing axis or introduces a new one.

  • Combining:

    • np.concatenate: joins along an existing axis (no new dimension).

    • np.stack: joins along a new axis, increasing dimensionality by one.

    • np.vstack: stacks row-wise (axis 0), promoting 1-D to 2-D.

    • np.hstack: stacks column-wise (axis 1 for 2-D).

  • Splitting:

    • np.split(arr, n, axis): splits into n equal parts (raises if not divisible); can also take explicit split indices.

    • np.vsplit: splits along axis 0 (row-wise).

    • np.hsplit: splits along axis 1 (column-wise).

    • np.array_split allows uneven splits without error.

  • Mental model: stack adds an axis, concatenate/vstack/hstack extend an axis; split is the inverse of concatenate.

python

a, b = np.array([1, 2]), np.array([3, 4]) np.concatenate((a, b)) # [1 2 3 4] np.stack((a, b)) # [[1 2],[3 4]] -> new axis np.split(np.arange(6), 3) # [array([0,1]), array([2,3]), array([4,5])]

Q41.
Explain the difference between ravel() and flatten() in NumPy regarding views and copies.

Mid

Both return a flattened 1-D array, but ravel() returns a view whenever possible (sharing memory), while flatten() always returns a fresh, independent copy.

  • ravel():

    • Returns a view for contiguous data, so it's faster and uses no extra memory.

    • Modifying the result can modify the original array.

    • Falls back to a copy when a view isn't possible (e.g. non-contiguous layout).

  • flatten():

    • Always allocates and copies, so changes never affect the original.

    • Slightly slower and uses more memory.

  • Choosing: Use ravel() for performance when you won't mutate, flatten() when you need a guaranteed independent copy.

Q42.
When would you use np.pad() and what are its key parameters for array padding?

Mid

np.pad() adds elements around the edges of an array, useful for tasks like preparing images for convolution, adding borders, or aligning arrays to a required size.

  • array: The input array to be padded.

  • pad_width: How many elements to add before and after along each axis, e.g. ((top, bottom), (left, right)) for 2-D.

  • mode: How to fill new elements: 'constant' (default), 'edge', 'reflect', 'symmetric', 'wrap', etc.

  • constant_values: The value(s) used when mode='constant' (defaults to 0).

  • Typical uses: Zero-padding feature maps, extending signal edges before filtering, or making arrays broadcast-compatible.

python

a = np.array([[1, 2], [3, 4]]) np.pad(a, ((1, 1), (2, 2)), mode='constant', constant_values=0) # adds 1 row top/bottom, 2 cols left/right, filled with 0

Q43.
What do np.squeeze and np.expand_dims do, and when would you use them?

Mid

They adjust an array's dimensionality: np.squeeze removes axes of length 1, while np.expand_dims inserts a new length-1 axis: both are cheap reshapes that return views.

  • np.squeeze(a, axis=None):

    • Drops all size-1 dimensions, e.g. shape (1, 3, 1) becomes (3,).

    • Pass axis to remove only a specific unit axis (errors if that axis isn't size 1).

    • Useful to collapse trailing dims from operations like keepdims=True reductions or single-channel results.

  • np.expand_dims(a, axis):

    • Adds a new axis of length 1 at the given position, e.g. (3,) becomes (1, 3) or (3, 1).

    • Equivalent to indexing with np.newaxis / None.

  • When to use:

    • Align shapes for broadcasting (add an axis so arrays line up).

    • Add or strip a batch/channel dimension when feeding ML models.

python

a = np.array([[1, 2, 3]]) # shape (1, 3) np.squeeze(a).shape # (3,) np.expand_dims(a, 2).shape # (1, 3, 1)

Q44.
What does np.unique do, and how do parameters like return_counts and return_index work?

Mid

np.unique returns the sorted distinct values of an array, and its optional flags return extra bookkeeping arrays: counts, first indices, and inverse mappings.

  • Default behavior: Flattens the input and returns unique values in ascending order.

  • return_counts=True: Also returns how many times each unique value occurs: great for frequency tables/histograms of discrete data.

  • return_index=True: Returns the index in the original array where each unique value first appears.

  • return_inverse=True: Returns indices that reconstruct the original array from the unique values: unique[inverse] equals the input.

  • axis: Set axis=0 to find unique rows instead of unique scalars.

python

a = np.array([3, 1, 2, 1, 3]) vals, counts = np.unique(a, return_counts=True) # vals -> [1 2 3] # counts -> [2 1 2]

Q45.
What is the difference between np.tile and np.repeat?

Mid

Both replicate data, but np.tile repeats the whole array as a block, while np.repeat repeats each element in place.

  • np.tile(a, reps):

    • Stacks copies of the entire array, like laying tiles.

    • [1,2,3] tiled twice becomes [1,2,3,1,2,3].

    • reps can be a tuple to tile along multiple axes.

  • np.repeat(a, repeats, axis):

    • Repeats each element consecutively.

    • [1,2,3] repeated twice becomes [1,1,2,2,3,3].

    • repeats can be a per-element list, and axis controls which dimension expands.

  • Mnemonic: tile = repeat the pattern; repeat = repeat each element.

Q46.
Explain how boolean masking works in NumPy and why it is important for filtering or modifying elements based on conditions.

Mid

Boolean masking uses a boolean array of the same shape as the data to select or modify only the elements where the mask is True: a vectorized, loop-free way to filter by condition.

  • How the mask is built:

    • A comparison like a > 5 produces a boolean array elementwise.

    • Combine conditions with &, |, ~ (parenthesize each: (a>2) & (a<8)): Python's and/or don't work elementwise.

  • Filtering: a[mask] returns a 1D array of the matching elements (a copy).

  • Modifying in place: a[a < 0] = 0 assigns only to matching positions: concise conditional updates.

  • Why it matters: Runs in fast C loops, avoiding slow Python iteration, and expresses intent clearly.

python

a = np.array([-2, 3, -1, 5]) a[a < 0] = 0 # [0 3 0 5] positives = a[a > 0] # [3 5] (copy)

Q47.
Explain basic slicing, advanced indexing, and boolean mask indexing in NumPy, and how they differ in terms of returning views vs. copies.

Mid

NumPy has three indexing modes: basic slicing (start:stop:step) returns views, while advanced indexing (integer or boolean arrays) always returns copies.

  • Basic slicing:

    • Uses slices, integers, and np.newaxis, e.g. a[1:5, ::2].

    • Returns a view: shares memory with the original, so writes propagate back.

  • Advanced (fancy) indexing:

    • Indexing with an integer array/list, e.g. a[[0, 2, 3]].

    • Returns a copy: the result gathers scattered elements, so it can't be a view.

    • Can pick arbitrary elements and reorder/repeat them.

  • Boolean mask indexing:

    • A form of advanced indexing using a boolean array, e.g. a[a > 0].

    • Also returns a copy.

  • View vs copy caveat: Assignment like a[mask] = 0 still modifies the original (the copy rule applies to the read result, not to in-place assignment).

Q48.
How can you replace values in a NumPy array based on a condition using boolean indexing?

Mid

Build a boolean mask from your condition and assign to the masked positions, or use np.where to produce a new array with values chosen by condition.

  • In-place assignment: a[a > 100] = 100 clips large values; the right side can be a scalar or a matching-length array.

  • np.where(cond, x, y): Returns a new array: takes from x where cond is True, else from y. Non-destructive.

  • Multiple conditions: Combine with &/| and parentheses, e.g. a[(a<0) | (a>10)] = 0.

python

a = np.array([-5, 2, 200, 7]) a[a < 0] = 0 # in place -> [0 2 200 7] b = np.where(a > 100, 100, a) # new array -> [0 2 100 7]

Q49.
How do you perform advanced indexing to select elements from a multidimensional array based on a condition or an array of indices?

Mid

Advanced indexing passes integer arrays or a boolean mask to gather arbitrary elements: for multidimensional arrays you supply one index array per axis, and they are broadcast together to pick coordinate-wise.

  • Integer-array (fancy) indexing:

    • a[[0, 2], [1, 3]] selects elements at (0,1) and (2,3): the index arrays pair up elementwise.

    • Index arrays broadcast, so shapes need not match exactly.

    • Always returns a copy, and result shape follows the broadcasted index shape.

  • Boolean-condition indexing:

    • a[a > 0] flattens matching elements into a 1D array.

    • Use np.nonzero(mask) or np.argwhere(mask) to recover the coordinates of matches.

  • Selecting whole rows/columns: a[[0, 2], :] picks rows 0 and 2; mix a slice with an index array to grab structured subsets.

python

a = np.arange(12).reshape(3, 4) rows = np.array([0, 2]) cols = np.array([1, 3]) a[rows, cols] # elements (0,1) and (2,3) -> [1, 11] a[a % 2 == 0] # all even values (1D copy)

Q50.
Explain the use of slicing and indexing with NumPy arrays, including basic vs. advanced indexing.

Mid

Slicing and indexing extract subsets of an array. The key distinction: basic indexing (slices, integers) returns a view sharing memory, while advanced indexing (integer or boolean arrays) returns a copy.

  • Basic indexing:

    • Uses integers and slices like arr[1:4, ::2]; multi-dimensional via a comma-separated tuple.

    • Returns a view: modifying the result modifies the original.

  • Advanced (fancy) indexing:

    • Integer arrays: arr[[0, 2, 4]] selects arbitrary elements in any order.

    • Boolean masks: arr[arr > 0] selects elements where the mask is True.

    • Always returns a copy, so assignment back (arr[mask] = 0) still works but the returned array is independent.

  • Why the view vs copy distinction matters: Views avoid copying data (fast, memory-efficient) but mutations propagate; use .copy() when you need isolation.

python

a = np.arange(10) a[2:5] # view: array([2, 3, 4]) a[[2, 4, 6]] # copy: array([2, 4, 6]) a[a % 2 == 0] # copy via boolean mask

Q51.
Why must you use &, |, and ~ instead of the Python and/or/not keywords when combining boolean array conditions in NumPy?

Mid

Because Python's and, or, and not operate on a single truth value, they can't be applied element-wise to arrays and raise an ambiguity error; the bitwise operators &, |, ~ are overloaded by NumPy to combine boolean arrays element by element.

  • Why the keywords fail:

    • and/or call __bool__ on the whole array, which raises ValueError: The truth value of an array ... is ambiguous.

    • They cannot return an array, only a single object.

  • What the bitwise operators do: &, |, ~ map to np.logical_and/or/not element-wise, producing a boolean array.

  • Watch operator precedence: Bitwise operators bind tighter than comparisons, so parenthesize each condition: (a > 0) & (a < 5).

python

a = np.arange(6) a[(a > 1) & (a < 5)] # array([2, 3, 4]) # a[a > 1 and a < 5] # ValueError: ambiguous truth value

Q52.
What is the difference between indexing an array with arr[i, j] versus arr[i][j] in NumPy?

Mid

arr[i, j] indexes with a single tuple in one operation, while arr[i][j] is two sequential operations: index by i, then index the result by j. For basic access they give the same value, but they differ in efficiency and in behavior with advanced indexing.

  • arr[i, j] is one indexing call: NumPy sees the tuple (i, j) and resolves both dimensions together: single, efficient operation.

  • arr[i][j] is two calls: arr[i] builds an intermediate array, which is then indexed by j; slower and allocates a temporary.

  • They diverge with fancy indexing: With integer arrays, arr[i, j] pairs elements of i and j (broadcasting together), whereas arr[i][j] applies them in stages and can yield a different shape or result.

  • Rule of thumb: Prefer the comma form arr[i, j] for multi-dimensional access.

Q53.
Explain the concept of a NumPy Universal Function (ufunc), with examples, and discuss their significance.

Mid

A universal function (ufunc) is a function that operates element-wise on ndarrays, implemented in compiled C with support for broadcasting, type casting, and reductions. They are the core mechanism behind NumPy's fast vectorized math.

  • What makes it a ufunc:

    • Applies a scalar operation across every element without a Python loop.

    • Supports broadcasting so arrays of different but compatible shapes combine.

  • Examples:

    • Unary: np.sqrt, np.exp, np.sin, np.abs.

    • Binary: np.add, np.multiply, np.maximum (operators like + dispatch to these).

  • Extra methods on ufuncs: .reduce (e.g. np.add.reduce sums), .accumulate (cumulative), and .outer (all pairs).

  • Significance: They push looping into optimized C, giving concise syntax and large speedups over pure Python.

python

a = np.array([1, 4, 9]) np.sqrt(a) # array([1., 2., 3.]) np.add.reduce(a) # 14 (sum via ufunc reduce)

Q54.
Explain np.vectorize and clarify whether it provides a performance speedup or is primarily for convenience.

Mid

np.vectorize wraps a scalar Python function so it can be called on arrays with broadcasting semantics. It is a convenience/readability tool, not a performance tool: internally it still loops in Python, so it is essentially as slow as a manual loop.

  • What it provides:

    • Broadcasting and clean array-in/array-out syntax for a function written for scalars.

    • Handles output typing and shape so you don't write the loop yourself.

  • What it does NOT provide: No C-level speedup: the docs explicitly state it is "essentially a for loop" for convenience.

  • When to use it:

    • When no native vectorized/ufunc expression exists and readability matters more than speed.

    • Prefer true ufuncs, boolean masks, or np.where when a vectorized form is available.

python

def f(x): return x + 1 if x > 0 else 0 vf = np.vectorize(f) vf(np.array([-1, 2, 3])) # array([0, 3, 4]) -- convenient, not fast

Q55.
Why are vectorized operations and ufuncs preferred over explicit Python loops for numerical computations, and what are the performance advantages?

Mid

Vectorized operations and ufuncs push the per-element work into optimized, compiled C code operating on contiguous memory, avoiding Python's per-iteration interpreter overhead. The result is code that is both faster (often 10x to 100x) and more concise than an explicit loop.

  • Why loops are slow: Each iteration incurs interpreter overhead: bytecode dispatch, boxing/unboxing of Python objects, and dynamic type checks.

  • Why vectorization is fast:

    • The loop runs once in C over a typed, contiguous buffer, so there is no per-element Python overhead.

    • Better cache locality and use of CPU SIMD instructions; some ufuncs are multithreaded or delegate to BLAS.

  • Secondary benefits: Less memory churn (no millions of Python int/float objects) and clearer, more declarative code.

  • Caveat: Vectorization can create large temporary arrays; watch memory and consider in-place operations (out=) for very large data.

Q56.
How are element-wise operations performed efficiently in NumPy, and what are Universal Functions (ufuncs)?

Mid

NumPy performs element-wise operations efficiently by pushing the loop down into precompiled C code that runs over contiguous memory, avoiding the Python interpreter per element. The functions that do this are called ufuncs (universal functions): vectorized functions that operate element-by-element on arrays with broadcasting, type casting, and optional output support.

  • What a ufunc is:

    • A function that applies a scalar operation to each element of an array (or arrays) in a fast C loop, e.g. np.add, np.sqrt, np.exp.

    • Operators like +, *, ** are just syntactic sugar for ufuncs.

  • Why it is efficient:

    • The iteration happens in C, not Python, so there is no per-element interpreter overhead.

    • Homogeneous, contiguous data enables CPU cache efficiency and sometimes SIMD vectorization.

  • Built-in features of ufuncs:

    • Broadcasting: mismatched but compatible shapes align automatically.

    • Type casting and an optional out= argument to write results in place.

python

import numpy as np a = np.array([1, 4, 9]) np.sqrt(a) # ufunc -> array([1., 2., 3.]) a + 10 # sugar for np.add(a, 10)

Q57.
How is vectorization related to broadcasting in NumPy? Explain what vectorized operations are and why they are faster than Python loops.

Mid

Vectorization means expressing an operation over whole arrays at once so the looping runs in optimized C rather than Python; broadcasting is the rule set that lets vectorized operations work on arrays of different but compatible shapes without copying data. They are complementary: vectorization is the execution model, broadcasting is how shapes are aligned within it.

  • What vectorized operations are: A single array-level expression (e.g. a + b) that applies to all elements in one C-level pass.

  • Why they are faster than Python loops:

    • No per-element interpreter overhead: the loop lives in compiled C.

    • Contiguous typed memory gives cache locality and enables SIMD; no per-element Python object boxing.

  • How broadcasting fits in:

    • It virtually stretches smaller arrays to match larger ones (without materializing copies), so you can vectorize across mismatched shapes.

    • Example: adding a shape (3,) row to a (4,3) matrix applies it to each row.

python

# Slow: Python loop out = [x * 2 for x in range(1_000_000)] # Fast: vectorized a = np.arange(1_000_000) out = a * 2 # Broadcasting inside a vectorized op m = np.ones((4, 3)) r = np.array([1, 2, 3]) m + r # r stretched across all 4 rows

Q58.
Explain the difference between element-wise multiplication and matrix multiplication in NumPy.

Mid

Element-wise multiplication (*) multiplies corresponding entries and returns an array of the same shape; matrix multiplication (@ or np.matmul) computes dot products across rows and columns following linear-algebra rules. They are different operations that only coincide for special cases.

  • Element-wise (*, np.multiply): Requires equal or broadcastable shapes; result[i,j] = a[i,j] * b[i,j].

  • Matrix multiplication (@, np.matmul, np.dot):

    • Inner dimensions must match: (m,n) @ (n,p) -> (m,p).

    • Each output entry is a sum of products (dot product), not a single product.

  • Common pitfall: On a np.matrix object * means matrix multiply, but on the standard ndarray it is element-wise. Prefer ndarray with explicit @.

python

A = np.array([[1, 2], [3, 4]]) B = np.array([[5, 6], [7, 8]]) A * B # element-wise -> [[5, 12], [21, 32]] A @ B # matrix mult -> [[19, 22], [43, 50]]

Q59.
How can you leverage NumPy's argsort() function, and in what scenarios is it particularly useful?

Mid

np.argsort() returns the indices that would sort an array, rather than the sorted values themselves: it gives you the permutation to reorder data indirectly.

  • Returns indices, not values: arr[np.argsort(arr)] reproduces the sorted array; the indices tell you where each sorted element came from.

  • Indirect / parallel sorting: Sort one array and apply the same ordering to related arrays (e.g. reorder labels by score).

  • Top-k selection: Slice the result to get largest/smallest: np.argsort(arr)[-k:] for the k largest indices.

  • Ranking: Applying argsort twice yields the rank of each element.

  • Controls: kind (algorithm, e.g. 'stable') and axis for row/column-wise sorting.

python

scores = np.array([50, 90, 70]) order = np.argsort(scores) # [0, 2, 1] names[order] # names sorted by score top2 = np.argsort(scores)[-2:] # indices of 2 highest

Q60.
What is the keepdims parameter in NumPy aggregations, and why is it useful?

Mid

keepdims=True makes an aggregation retain the reduced axes as size-1 dimensions instead of dropping them, keeping the result's rank equal to the input so it broadcasts cleanly back against the original.

  • Default drops the axis: a.sum(axis=1) on a (3,4) array gives shape (3,); with keepdims=True it gives (3,1).

  • Why it matters: broadcasting: The (3,1) result lines up with the (3,4) original, so operations like normalization work without manual reshaping.

  • Common uses: Row/column means for centering, softmax denominators, per-axis normalization.

python

x = np.random.rand(3, 4) row_mean = x.mean(axis=1, keepdims=True) # (3,1) centered = x - row_mean # broadcasts, no reshape

Q61.
What is broadcasting in NumPy? Explain the broadcasting rules and how it facilitates operations between arrays of different shapes without copying data.

Mid

Broadcasting is NumPy's set of rules for performing element-wise operations on arrays of different shapes by virtually stretching the smaller array across the larger one, without ever copying the data.

  • The rules (compared right to left):

    1. Align shapes by their trailing dimensions.

    2. Two dimensions are compatible if they are equal, or one of them is 1.

    3. A size-1 (or missing) dimension is stretched to match the other; otherwise it's an error.

  • No data copy: The stretched array is not materialized; NumPy uses a stride of 0 along the broadcast axis to reread the same values, saving memory.

  • Common patterns: Scalar with array; a (3,1) column with a (1,4) row producing a (3,4) grid; subtracting a per-column mean of shape (4,) from a (100,4) matrix.

python

a = np.arange(3).reshape(3, 1) # (3,1) b = np.arange(4).reshape(1, 4) # (1,4) a + b # (3,4) outer sum, no copies

Q62.
How do ufuncs integrate seamlessly with NumPy's broadcasting rules?

Mid

Ufuncs are element-wise functions that call broadcasting internally: before applying the operation they align the shapes of their inputs using the same broadcasting rules, so a scalar, a row, and a matrix can all combine without explicit loops.

  • Ufuncs operate element by element: Functions like np.add, np.multiply, np.exp apply the same scalar operation across every aligned element.

  • They broadcast inputs first:

    • Shapes are compared trailing-dimension first; each dimension must be equal or one of them must be 1.

    • Size-1 and missing dimensions are virtually stretched (via stride 0) to the common shape, no data copied.

  • Result shape is the broadcasted shape: The ufunc allocates an output of the common shape and fills it element-wise.

  • Extra ufunc controls: The out= argument reuses a buffer to avoid allocation; where= applies conditionally.

python

a = np.arange(3) # shape (3,) b = np.arange(3).reshape(3, 1) # shape (3,1) a + b # broadcasts to (3,3) element-wise

Q63.
How do you add a new axis to a NumPy array using np.newaxis or np.expand_dims, and why is this useful for broadcasting?

Mid

Both insert a new length-1 axis, raising the array's dimensionality so it lines up for broadcasting: np.newaxis is an indexing trick, and np.expand_dims is the function form that takes an explicit axis position.

  • np.newaxis inside indexing: It is an alias for None; place it where you want the new axis: a[:, np.newaxis].

  • np.expand_dims(a, axis): Explicit and readable: np.expand_dims(a, 1) is the same as a[:, np.newaxis].

  • Why it helps broadcasting: Turning a (3,) vector into (3,1) lets it broadcast against a (1,3) row to form a (3,3) outer combination.

  • Both return views: No data is copied; only the shape and strides metadata change.

python

a = np.array([1, 2, 3]) # (3,) col = a[:, np.newaxis] # (3,1) row = a[np.newaxis, :] # (1,3) col + row # (3,3) via broadcasting

Q64.
What is the difference between a view and a copy in NumPy? How can you tell if an operation returns a view or a copy, and why is this distinction important for aliasing bugs?

Mid

A view shares the same underlying data buffer as the original array (only its metadata differs), while a copy owns a separate buffer. This matters because writing to a view also mutates the source, causing aliasing bugs that are hard to trace.

  • Views (no data copied):

    • Basic slicing (a[1:4]), reshape, .T, and np.newaxis typically return views.

    • Mutating a view propagates to the parent array.

  • Copies (independent data): Fancy indexing (integer or boolean arrays) and explicit .copy() return copies.

  • How to tell them apart: Check arr.base: it is None for a copy/owner and points to the source for a view.

  • Why it matters: An in-place edit through a view silently changes data elsewhere; call .copy() when you need isolation.

python

a = np.arange(5) v = a[1:4] # view v[0] = 99 a # array([ 0, 99, 2, 3, 4]) -> parent changed v.base is a # True

Q65.
Explain the difference between a shallow copy and a deep copy in NumPy.

Mid

A shallow copy shares the underlying data buffer with the original (a view), so edits to the elements are seen by both; a deep copy duplicates the data into an independent buffer, so the two arrays no longer affect each other.

  • Shallow copy (view):

    • Created by arr.view(), basic slicing, or copy.copy(arr).

    • New array object and metadata, but .base points to the shared data.

  • Deep copy (independent):

    • Created by arr.copy() or copy.deepcopy(arr).

    • Owns its buffer; .base is None and mutations stay local.

  • Object-dtype nuance: For dtype=object arrays, .copy() copies the references, not the referenced Python objects; use copy.deepcopy for full independence.

python

a = np.arange(4) s = a.view() # shallow: shares data d = a.copy() # deep: independent s[0] = 99 # changes a too d[1] = 77 # a unaffected

Q66.
What are some common pitfalls or gotchas when working with NumPy arrays, especially concerning views vs. copies and integer overflow?

Mid

The two classic traps are silently mutating shared data through a view and silently wrapping around fixed-width integers: both produce wrong results with no error.

  • Views vs. copies:

    • Basic slicing (e.g. a[1:5]) returns a view sharing memory, so writing to it mutates the original.

    • Fancy indexing (integer/boolean arrays) and most reshapes that can't be strided return copies.

    • Check with arr.base (a view's base points at the owner); use .copy() when you need independence.

  • Integer overflow:

    • Fixed-width dtypes (int32, int64) wrap silently: np.int8(127)+1 == -128.

    • Sums/products of large arrays can overflow the accumulator; pass dtype= to widen, or use a floating type.

  • Other common gotchas:

    • Broadcasting mismatches that silently expand instead of erroring as expected.

    • In-place ops with mismatched dtype (e.g. int_arr += 0.5) truncate rather than upcast.

    • Comparing floats or np.nan with == (nan != nan); use np.isclose/np.isnan.

Q67.
How does NumPy handle large datasets efficiently in terms of memory management and performance optimizations?

Mid
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut
Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugit, sed quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt. Neque porro quisquam est, qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit, sed quia non numquam eius modi tempora incidunt ut labore et dolore magnam aliquam quaerat voluptatem.

Q68.
How do you save and load NumPy arrays to disk using .npy and .npz files, and how does that differ from text formats like loadtxt/genfromtxt?

Mid
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut
Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugit, sed quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt. Neque porro quisquam est, qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit, sed quia non numquam eius modi tempora incidunt ut labore et dolore magnam aliquam quaerat voluptatem.

Q69.
How can you handle and manipulate arrays with missing or infinite values in NumPy, such as np.nan, np.inf, nan-aware functions, and masked arrays?

Mid
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut
Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugit, sed quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt. Neque porro quisquam est, qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit, sed quia non numquam eius modi tempora incidunt ut labore et dolore magnam aliquam quaerat voluptatem.

Q70.
How does NumPy represent missing (np.nan) and infinite (np.inf) values, and what are the implications for operations and aggregations?

Mid
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut
Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugit, sed quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt. Neque porro quisquam est, qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit, sed quia non numquam eius modi tempora incidunt ut labore et dolore magnam aliquam quaerat voluptatem.

Q71.
What happens when a fixed-width integer array overflows, and why does NumPy wrap around silently?

Mid
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut
Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugit, sed quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt. Neque porro quisquam est, qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit, sed quia non numquam eius modi tempora incidunt ut labore et dolore magnam aliquam quaerat voluptatem.

Q72.
Why does NaN != NaN evaluate to True, and what are the implications for comparing or checking floating-point arrays?

Mid
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut
Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugit, sed quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt. Neque porro quisquam est, qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit, sed quia non numquam eius modi tempora incidunt ut labore et dolore magnam aliquam quaerat voluptatem.

Q73.
Explain the relationship between NumPy arrays and Pandas DataFrames/Series, when you would use one over the other, and how they interoperate.

Mid
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut
Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugit, sed quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt. Neque porro quisquam est, qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit, sed quia non numquam eius modi tempora incidunt ut labore et dolore magnam aliquam quaerat voluptatem.

Q74.
How do you compute the dot product of two NumPy arrays, and how does the @ operator differ from element-wise multiplication with *?

Mid
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut
Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugit, sed quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt. Neque porro quisquam est, qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit, sed quia non numquam eius modi tempora incidunt ut labore et dolore magnam aliquam quaerat voluptatem.

Q75.
What is the purpose of the np.linalg module in NumPy?

Mid
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut
Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugit, sed quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt. Neque porro quisquam est, qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit, sed quia non numquam eius modi tempora incidunt ut labore et dolore magnam aliquam quaerat voluptatem.

Q76.
What are structured arrays in NumPy, and when would you use them?

Mid
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut
Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugit, sed quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt. Neque porro quisquam est, qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit, sed quia non numquam eius modi tempora incidunt ut labore et dolore magnam aliquam quaerat voluptatem.

Q77.
Explain the importance of choosing the correct dtype and how type promotion and casting rules work in NumPy.

Senior
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut
Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugit, sed quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt. Neque porro quisquam est, qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit, sed quia non numquam eius modi tempora incidunt ut labore et dolore magnam aliquam quaerat voluptatem.

Q78.
What are the ufunc methods like reduce, accumulate, and outer, and what do they do?

Senior
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut
Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugit, sed quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt. Neque porro quisquam est, qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit, sed quia non numquam eius modi tempora incidunt ut labore et dolore magnam aliquam quaerat voluptatem.

Q79.
Explain the internal rules of broadcasting in NumPy and when it might lead to unexpected results or shape mismatch errors.

Senior
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut
Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugit, sed quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt. Neque porro quisquam est, qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit, sed quia non numquam eius modi tempora incidunt ut labore et dolore magnam aliquam quaerat voluptatem.

Q80.
What are NumPy strides and how do they enable efficient array manipulations like reshaping and transposing without copying data?

Senior
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut
Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugit, sed quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt. Neque porro quisquam est, qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit, sed quia non numquam eius modi tempora incidunt ut labore et dolore magnam aliquam quaerat voluptatem.

Q81.
Discuss NumPy's memory model, including contiguous memory, C-order (row-major) vs. Fortran-order (column-major), and how strides implement views, reshape, and transpose without copying.

Senior
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut
Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugit, sed quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt. Neque porro quisquam est, qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit, sed quia non numquam eius modi tempora incidunt ut labore et dolore magnam aliquam quaerat voluptatem.

Q82.
How can you programmatically check if an array is a view or a copy, for example using .base or __array_interface__?

Senior
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut
Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugit, sed quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt. Neque porro quisquam est, qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit, sed quia non numquam eius modi tempora incidunt ut labore et dolore magnam aliquam quaerat voluptatem.

Q83.
How does NumPy's memory model, such as contiguous memory and homogeneity, contribute to its performance, and what strategies minimize memory copies?

Senior
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut
Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugit, sed quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt. Neque porro quisquam est, qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit, sed quia non numquam eius modi tempora incidunt ut labore et dolore magnam aliquam quaerat voluptatem.

Q84.
How does NumPy interoperate with other libraries at zero copy through the array interface or buffer protocol?

Senior
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut
Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugit, sed quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt. Neque porro quisquam est, qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit, sed quia non numquam eius modi tempora incidunt ut labore et dolore magnam aliquam quaerat voluptatem.

Q85.
What strategies would you employ to reduce the memory footprint when working with large NumPy arrays while preserving data accuracy?

Senior
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut
Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugit, sed quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt. Neque porro quisquam est, qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit, sed quia non numquam eius modi tempora incidunt ut labore et dolore magnam aliquam quaerat voluptatem.

Q86.
How do you handle memory-mapped files in NumPy for large datasets, and what are the benefits?

Senior
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut
Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugit, sed quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt. Neque porro quisquam est, qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit, sed quia non numquam eius modi tempora incidunt ut labore et dolore magnam aliquam quaerat voluptatem.

Q87.
What strategies can you use to optimize NumPy code for better performance, including avoiding hidden copies, using in-place operations, and the out= parameter?

Senior
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut
Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugit, sed quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt. Neque porro quisquam est, qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit, sed quia non numquam eius modi tempora incidunt ut labore et dolore magnam aliquam quaerat voluptatem.

Q88.
Explain the concept and use of masked arrays (np.ma) in NumPy.

Senior
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut
Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugit, sed quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt. Neque porro quisquam est, qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit, sed quia non numquam eius modi tempora incidunt ut labore et dolore magnam aliquam quaerat voluptatem.