Your country

Tools that support it use your country for local currency, number formats, units and paper size. Your choice is saved only in this browser.

Type a name or a two-letter code. Use the up and down arrow keys to move through the countries, Enter to choose one and Escape to close.

NumPy & SciPy for Scientific Computing Module 2

Indexing, reshaping and vectorised operations interview questions

Interview questions on indexing, reshaping and vectorised operations: warm-ups, then what each harder question tests and how a good answer starts.

18 questions: 6 warm-ups and 12 with model answers · Levels: Fresher to senior

Warm-up questions

Short questions with short answers, each answered in full.

  1. Fresher

    What is the difference between a view and a copy in NumPy, and how can you tell which one you have?

    Answered in the lesson Indexing, slicing and views

  2. Fresher

    What does a[a > 0] return, and how is it different from np.where(a > 0, a, 0)?

    Answered in the lesson Boolean masks and fancy indexing

  3. Fresher

    What is the difference between np.concatenate and np.stack?

    Answered in the lesson Reshaping, stacking and splitting arrays

  4. Fresher

    What is a ufunc, and why is np.add(a, b) faster than a Python loop over the elements?

    Answered in the lesson Universal functions and vectorised arithmetic

  5. Fresher

    For an array of shape (5, 4), what do sum(axis=0) and sum(axis=1) return, and what does keepdims=True change?

    Answered in the lesson Reductions, axes, NaN and masked data

  6. Fresher

    What is the difference between np.sort and np.argsort, and when do you need a stable sort?

    Answered in the lesson Sorting, searching, counting and set operations

Questions with model answers

What each question tests, the first step of a good answer and the follow-ups to expect.

  1. Fresher to mid

    A helper standardises the first three columns of the array it receives: block = data[:, :3], then block -= block.mean(axis=0) and block /= block.std(axis=0). Callers report that their own arrays change. Explain why, and fix the helper without copying the whole input.

    What it tests
    Knowing that basic slices are views and that in-place operators write through them, estimating what a fix costs, and testing that a function leaves its input alone.
    First step
    Name the mechanism: data[:, :3] is basic indexing, so block is a view over the caller's buffer, and -= and /= write into it. np.shares_memory(block, data) confirms it. Then decide the contract: a helper that returns a new result must not write to its input, so either copy only the three columns or let the arithmetic build a new array.
    Follow-ups

    From the lesson Indexing, slicing and views

    Model answer, Pro. Model answers open with any pass; prices are in the notice on this page.

    Opening the model answers with your pass…

    Model answers open with any MySmartCoPilot pass.

    • Pro pass · 1 week₹79$2.99
    • 30 days₹179$5.99
    • 1 year₹1,699$45

    One payment; a pass never renews. The price shown is the total you pay: no fees or charges are added at checkout.

    It also opens every other in-depth part in Learn and every Pro tool. Sales are final, except where the law gives you a right to withdraw, for example in the EU and the UK (refund policy).

    In the answer:

    • Model answer
    • Follow-up answers
    • Common mistakes
    • Rubric
    • Variants
    • about 3 minutes
  2. Mid to senior

    A service loads a 2 GB float64 array for each request and keeps its first 100 rows in an in-memory cache keyed by file. The cached rows add up to a few megabytes, yet the process is killed for using too much memory after a few dozen requests. Explain what is happening and fix it.

    What it tests
    Knowing that a view keeps its base array alive, estimating the memory that really stays allocated, and choosing a fix that releases it.
    First step
    Put numbers on both sides. With 10,000 float64 values a row, 100 rows are 8 MB, but arr[:100] is a view whose base is the whole 2 GB array, so 40 cached files hold about 80 GB. Check one entry: entry.base is the full array and entry.base.nbytes is 2 GB. Then cache arr[:100].copy(), which owns its 8 MB.
    Follow-ups

    From the lesson Indexing, slicing and views

    Model answer, Pro.

    In the answer:

    • Model answer
    • Follow-up answers
    • Common mistakes
    • Rubric
    • Variants
    • about 3 minutes
  3. Fresher to mid

    A teammate counts 10 million event codes, integers from 0 to 999, with counts[codes] += 1. No error is raised, but the counts add up to 1,000 and every code looks equally rare on the dashboard. Explain what happened, replace the line, and say which replacement you would choose and why.

    What it tests
    Knowing that x[idx] += 1 reads, adds and writes back, so a repeated index counts once, and choosing between np.bincount and np.add.at.
    First step
    Read the symptom: a total of 1,000 for 10 million events means that each code was counted exactly once. counts[codes] += 1 reads counts[codes] into a copy, adds 1 and writes the copy back, so every repeat of a code writes the same 1. Count every occurrence instead: counts = np.bincount(codes, minlength=1000).
    Follow-ups

    From the lesson Boolean masks and fancy indexing

    Model answer, Pro.

    In the answer:

    • Model answer
    • Follow-up answers
    • Common mistakes
    • Rubric
    • Variants
    • about 3 minutes
  4. Mid to senior

    frames has shape (100, 480, 640). frames[7, :, [10, 20, 30]] should give 480 rows by 3 columns, but its shape is (3, 480), and the code that follows quietly works on transposed data. Explain the rule behind the shape and give two ways to get (480, 3).

    What it tests
    Knowing where NumPy puts the axis of advanced indexes that a slice separates, and indexing so that the shape is the one intended.
    First step
    Count the advanced indexes: the integer 7 is one and the list [10, 20, 30] the other, and the slice in the middle separates them. NumPy's rule then puts the axis they produce, length 3, first and the sliced axis of 480 after it. Index in two steps instead, frames[7][:, [10, 20, 30]], or use np.take(frames[7], [10, 20, 30], axis=1).
    Follow-ups

    From the lesson Boolean masks and fancy indexing

    Model answer, Pro.

    In the answer:

    • Model answer
    • Follow-up answers
    • Common mistakes
    • Rubric
    • Variants
    • about 3 minutes
  5. Fresher to mid

    A model expects image batches as (batch, channels, height, width). A colleague converts a (32, 224, 224, 3) batch with batch.reshape(32, 3, 224, 224). The shapes match and training runs, but accuracy stays poor. What went wrong, how do you fix it, and what does the fix cost?

    What it tests
    Knowing that reshape keeps the order of the values and never moves axes, choosing transpose or moveaxis instead, and knowing when a contiguous copy is needed.
    First step
    Check one pixel. In the original, batch[0, 10, 20] holds the three channel values of one pixel side by side. After reshape(32, 3, 224, 224) they are no longer at out[0, :, 10, 20]: reshape kept the flat order and cut it into new axes, mixing pixels and channels. Moving an axis needs np.transpose(batch, (0, 3, 1, 2)) or np.moveaxis(batch, -1, 1).
    Follow-ups

    From the lesson Reshaping, stacking and splitting arrays

    Model answer, Pro.

    In the answer:

    • Model answer
    • Follow-up answers
    • Common mistakes
    • Rubric
    • Variants
    • about 3 minutes
  6. Fresher to mid

    A script builds a table of 100,000 rows with result = np.vstack([result, row]) inside a loop and takes many seconds, although 10,000 rows took a fraction of a second. Explain why the time grows so fast, estimate the work, and rewrite it.

    What it tests
    Knowing that every join copies, estimating the quadratic cost of growing an array, and choosing a list or a preallocated array instead.
    First step
    Each vstack makes a new array and copies everything joined so far, so call k copies k rows: about n²/2 row copies for n rows, 5 billion for 100,000 rows, where copying each row once would be 100,000. Collect the rows in a Python list and call np.array(rows) or np.vstack(rows) once at the end.
    Follow-ups

    From the lesson Reshaping, stacking and splitting arrays

    Model answer, Pro.

    In the answer:

    • Model answer
    • Follow-up answers
    • Common mistakes
    • Rubric
    • Variants
    • about 3 minutes
  7. Fresher to mid

    A daily report computes conversion = purchases / visits for 50,000 pages. Pages with no visits show inf or NaN on the dashboard, and the job's log fills with RuntimeWarnings. Make pages without visits show "no data", stop the warnings for the right reason, and say how you would test the fix.

    What it tests
    Using where= with out= to avoid the division instead of hiding its warnings, choosing a fill that cannot be mistaken for a rate, and testing the edge cases.
    First step
    Name the cause: visits is 0 for some pages, so the division runs and produces inf (x / 0) and NaN (0 / 0). Silencing it with np.errstate would keep those values. Avoid the division instead: start out as an array of NaN, the marker for no data, and divide only where visits > 0, with np.divide(purchases, visits, out=out, where=visits > 0).
    Follow-ups

    From the lesson Universal functions and vectorised arithmetic

    Model answer, Pro.

    In the answer:

    • Model answer
    • Follow-up answers
    • Common mistakes
    • Rubric
    • Variants
    • about 3 minutes
  8. Fresher to mid

    Brightening a uint8 image with img + 60 turns some bright pixels nearly black, and averaging two frames with (a + b) / 2 gives values that are far too small in bright areas. Explain both, and fix them without float copies of every frame where they are not needed.

    What it tests
    Knowing that the input dtypes choose the ufunc loop, so uint8 arithmetic wraps at 256, and choosing a wider dtype, clipping or an overflow-free formula with a stated memory cost.
    First step
    Work one pixel through: 200 + 60 = 260 does not fit uint8, which holds 0 to 255, so the uint8 loop keeps 260 − 256 = 4, a dark pixel. In (a + b) / 2 the sum wraps before the division: 200 + 100 becomes 44, and 44 / 2 = 22. Do the arithmetic in a wider type, for example with dtype=np.int16, and clip back to 0 to 255.
    Follow-ups

    From the lesson Universal functions and vectorised arithmetic

    Model answer, Pro.

    In the answer:

    • Model answer
    • Follow-up answers
    • Common mistakes
    • Rubric
    • Variants
    • about 3 minutes
  9. Fresher to mid

    A course has 300 students and 6 papers, and the results table holds NaN for papers a student missed. You are asked for a ranking. Compare ranking by np.nansum and by np.nanmean, say what each does to students who missed papers, and propose the rule you would use.

    What it tests
    Seeing that the choice of reduction is a decision about fairness, knowing what the nan-functions divide by, and handling students with too few marks explicitly.
    First step
    Work a small case: a student with 92, 88 and 85 who missed one paper has a nansum of 265, below a student with four marks averaging 73, but a nanmean of 88.33, above nearly everyone. nansum treats a missed paper as 0 and nanmean ignores it. Count the papers sat per student with np.count_nonzero(~np.isnan(marks), axis=1) before choosing.
    Follow-ups

    From the lesson Reductions, axes, NaN and masked data

    Model answer, Pro.

    In the answer:

    • Model answer
    • Follow-up answers
    • Common mistakes
    • Rubric
    • Variants
    • about 3 minutes
  10. Mid to senior

    Your p95 latency computed with NumPy from 1,000 samples differs from the p95 your monitoring dashboard shows for the same samples. Explain how both numbers can be correct, how you would check what each one does, and what you would standardise on.

    What it tests
    Knowing that percentiles of finite samples depend on the method, and that monitoring tools often estimate from bucketed or sketched data, and making a choice that is stated and reproducible.
    First step
    Separate the two possible causes. First the method: np.percentile defaults to linear interpolation, while other tools may use another of the nine Hyndman and Fan methods or a nearest-rank rule. Second the data: many monitoring systems estimate percentiles from histogram buckets or sketches, not from the raw samples. Compute NumPy's p95 with several methods and compare.
    Follow-ups

    From the lesson Reductions, axes, NaN and masked data

    Model answer, Pro.

    In the answer:

    • Model answer
    • Follow-up answers
    • Common mistakes
    • Rubric
    • Variants
    • about 3 minutes
  11. Mid to senior

    A dashboard shows the 50 fastest of the day's 20 million delivery times, refreshed every minute, and the job that builds it sorts the whole array each time. What would you do instead, why is it faster, and how do you return the 50 in order with ties broken by delivery ID?

    What it tests
    Choosing partition over a full sort for the k smallest, explaining the cost difference, and keeping a defined order for ties when partition does not.
    First step
    Only the 50 smallest values matter, so a full sort does far more work than needed. np.argpartition(times, 49)[:50] finds their positions with work that grows linearly with n; sorting just those 50 then costs almost nothing. Partition gives no order and no rule for ties, so finish with np.lexsort((ids[top], times[top])).
    Follow-ups

    From the lesson Sorting, searching, counting and set operations

    Model answer, Pro.

    In the answer:

    • Model answer
    • Follow-up answers
    • Common mistakes
    • Rubric
    • Variants
    • about 3 minutes
  12. Mid to senior

    An event log of 5 million rows repeats an order ID whenever a message was sent twice. Keep the first occurrence of each ID in the original order, report how many rows were duplicates, and explain why np.unique on its own gives a different answer.

    What it tests
    Knowing what np.unique returns and in which order, using return_index and return_counts, and counting duplicates without a Python loop.
    First step
    np.unique sorts the IDs, so on its own it loses the original order. Ask it for the first positions instead: values, first, counts = np.unique(ids, return_index=True, return_counts=True). Sorting first restores the order of first appearance, so rows[np.sort(first)] keeps one row per ID, and len(ids) - len(values) is the number of duplicate rows.
    Follow-ups

    From the lesson Sorting, searching, counting and set operations

    Model answer, Pro.

    In the answer:

    • Model answer
    • Follow-up answers
    • Common mistakes
    • Rubric
    • Variants
    • about 3 minutes

All NumPy & SciPy for Scientific Computing interview questions · The NumPy & SciPy for Scientific Computing track

Quick answers and tool search

Type to search tools or to get a quick answer, for example 18% of 2500. Use the up and down arrow keys to move through the results, Enter to choose, and Escape to close.