NumPy Interview Questions for Data Roles
NumPy questions check whether you understand what an array really is: a block of typed memory with a shape. Ten questions, answered on 1,599 real wine samples with NumPy 2, cover axes, views versus copies, broadcasting, silent integer overflow, NaN, float comparison, ties in top-N, vectorisation and seeds.
GloryTecks Team
Training & Placement Faculty
Last updated: 8 October 2026
NumPy interview questions are less about function names than about what an array is: one block of memory, one data type, and a shape that says how to read it. Most surprises in NumPy follow from that. A slice shares the memory, an integer type has fixed room, shapes must line up, and NaN spreads through arithmetic. The ten questions below are answered on real data with NumPy 2, so each behaviour is shown rather than asserted.
The data is the red wine part of the UCI Wine Quality set: 1,599 wines with eleven chemical measurements and a quality score from tasters (UCI: Wine Quality). Loaded with np.loadtxt, it is a 1,599 by 12 array of 64-bit floats.
import time
import numpy as np
with open("winequality-red.csv") as f: # UCI Wine Quality, red wines
names = [n.strip('"') for n in f.readline().strip().split(";")]
X = np.loadtxt("winequality-red.csv", delimiter=";", skiprows=1)
alcohol, quality = X[:, names.index("alcohol")], X[:, names.index("quality")]
print("N1 shape, dtype, and what axis means:", X.shape, X.dtype)
print(" mean of each column (axis=0), first 3:", X.mean(axis=0)[:3].round(3))
print(" mean of each row (axis=1), first 3: ", X.mean(axis=1)[:3].round(3))
print("\nN2 view or copy?")
first_rows = X[:5] # basic slicing: a view
picked = X[[0, 1, 2, 3, 4]] # fancy indexing: a copy
print(" slice shares memory:", np.shares_memory(X, first_rows), "| fancy index shares memory:", np.shares_memory(X, picked))
first_rows[0, 0] = -1.0
print(" after writing -1 into the slice, X[0, 0] =", X[0, 0])
X[0, 0] = 7.4 # put the original value back
print("\nN3 broadcasting")
z = (X - X.mean(axis=0)) / X.std(axis=0) # (1599, 12) with (12,) -> per-column z-scores
print(" column z-scores:", z.shape, "| column means now:", np.abs(z.mean(axis=0)).max() < 1e-12)
try:
X - X.mean(axis=1) # (1599, 12) with (1599,) does not line up
except ValueError as error:
print(" row means without keepdims:", str(error).strip())
print(" with keepdims:", (X - X.mean(axis=1, keepdims=True)).shape)
print("\nN4 masks and np.where")
good = quality >= 7
print(f" wines rated 7 or more: {good.sum()} ({good.mean():.1%})")
print(" mean alcohol, good vs rest:", alcohol[good].mean().round(2), alcohol[~good].mean().round(2))
label = np.where(good, "good", "other")
print(" labels:", {str(k): int(v) for k, v in zip(*np.unique(label, return_counts=True))})
print("\nN5 integer types overflow silently")
q8 = quality.astype(np.uint8)
best = q8 == 8
print(" a quality-8 wine times 50, as uint8:", (q8[best] * np.uint8(50))[0], "| as int64:", (q8[best].astype(np.int64) * 50)[0])
try:
q8 + 300 # NumPy 2: the Python int must fit the array's dtype
except OverflowError as error:
print(" uint8 + 300:", error)
print("\nN6 comparing floats")
print(" 0.1 + 0.2 == 0.3:", 0.1 + 0.2 == 0.3, "| np.isclose:", np.isclose(0.1 + 0.2, 0.3))
print("\nN7 one missing value poisons the mean")
gappy = alcohol.copy()
gappy[10] = np.nan
print(" mean:", gappy.mean(), "| nanmean:", np.nanmean(gappy).round(3))
print("\nN8 top 3 by alcohol, and the ties behind it")
top = np.argsort(alcohol, kind="stable")[::-1][:3]
part = np.argpartition(alcohol, -3)[-3:]
print(" argsort picks rows:", sorted(top.tolist()), "| argpartition picks rows:", sorted(part.tolist()))
print(" values:", alcohol[top], "| wines tied at", alcohol[top[-1]], "->", int((alcohol == alcohol[top[-1]]).sum()))
print("\nN9 loop vs vectorised z-scores")
start = time.perf_counter()
loop = [[(X[i, j] - X[:, j].mean()) / X[:, j].std() for j in range(X.shape[1])] for i in range(200)]
loop_time = (time.perf_counter() - start) / 200 * X.shape[0]
start = time.perf_counter()
vec = (X - X.mean(axis=0)) / X.std(axis=0)
vec_time = time.perf_counter() - start
print(" same answer:", np.allclose(loop, vec[:200]), f"| vectorised was about {loop_time / vec_time:,.0f}x faster (varies)")
print("\nN10 reproducible randomness")
a = np.random.default_rng(42).choice(len(X), size=5, replace=False)
b = np.random.default_rng(42).choice(len(X), size=5, replace=False)
print(" same seed, same sample:", a, (a == b).all())N1 shape, dtype, and what axis means: (1599, 12) float64
mean of each column (axis=0), first 3: [8.32 0.528 0.271]
mean of each row (axis=1), first 3: [ 6.212 10.255 8.308]
N2 view or copy?
slice shares memory: True | fancy index shares memory: False
after writing -1 into the slice, X[0, 0] = -1.0
N3 broadcasting
column z-scores: (1599, 12) | column means now: True
row means without keepdims: operands could not be broadcast together with shapes (1599,12) (1599,)
with keepdims: (1599, 12)
N4 masks and np.where
wines rated 7 or more: 217 (13.6%)
mean alcohol, good vs rest: 11.52 10.25
labels: {'good': 217, 'other': 1382}
N5 integer types overflow silently
a quality-8 wine times 50, as uint8: 144 | as int64: 400
uint8 + 300: Python integer 300 out of bounds for uint8
N6 comparing floats
0.1 + 0.2 == 0.3: False | np.isclose: True
N7 one missing value poisons the mean
mean: nan | nanmean: 10.424
N8 top 3 by alcohol, and the ties behind it
argsort picks rows: [652, 1269, 1270] | argpartition picks rows: [142, 144, 652]
values: [14.9 14. 14. ] | wines tied at 14.0 -> 7
N9 loop vs vectorised z-scores
same answer: True | vectorised was about 1,116x faster (varies)
N10 reproducible randomness
same seed, same sample: [1235 701 1045 142 692] TrueN1. What does axis=0 mean?
The axis you collapse. X.mean(axis=0) averages down the rows and returns one value per column, 12 values here; axis=1 averages across columns and returns one value per row. Saying "axis 0 is the direction the operation runs along, and it disappears from the result" is clearer than "rows" or "columns", which people mix up.
N2. When does indexing give a view, and when a copy?
Basic slicing such as X[:5] returns a view: a new array object over the same memory. Fancy indexing with a list or a boolean mask returns a copy (NumPy: copies and views). np.shares_memory confirmed it, and writing -1 into the slice changed X[0, 0] in the original. That is efficient for large data and dangerous when you meant to work on a copy; call .copy() when you need independence.
N3. How does broadcasting decide whether two shapes fit?
It compares shapes from the last dimension backwards; each pair must be equal or one of them must be 1 (NumPy: broadcasting). A (1599, 12) array minus the (12,) column means works, giving per-column z-scores. Subtracting the (1599,) row means fails, because 12 and 1599 do not match. keepdims=True keeps the row means as (1599, 1), and then it broadcasts. Reading the shapes out loud is the quickest way to answer this kind of question.
N4. How do you filter and label with a condition?
Build a boolean mask once and reuse it. 217 wines, 13.6%, were rated 7 or more, and their mean alcohol was 11.52% against 10.25% for the rest. np.where(mask, a, b) picks element by element, which is the vectorised form of an if-else.
N5. Can integer arithmetic go wrong without an error?
Yes. Fixed-size integers wrap around. Stored as uint8, which holds 0 to 255, a quality score of 8 times 50 gave 144 instead of 400, with no error. Sums of large integer arrays can overflow the same way in narrower types. NumPy 2 did tighten one case: under its NEP 50 promotion rules, adding the Python integer 300 to a uint8 array raises OverflowError, because 300 cannot be represented in that type (NEP 50). Older NumPy versions quietly promoted to a wider type instead, so name your version when you answer.
N6. Why is 0.1 + 0.2 == 0.3 False?
Because neither 0.1 nor 0.2 has an exact binary representation, and their sum differs from the stored 0.3 in the last bits. Compare floats with a tolerance: np.isclose for single values, np.allclose for arrays.
N7. What happens to a mean when one value is missing?
NaN spreads through arithmetic, so one missing reading made the whole mean nan. np.nanmean ignores missing values and returned 10.424. Say which one you want: sometimes a NaN result is the correct alarm that the data is incomplete.
N8. How do you get the top 3 values, and what about ties?
np.argsort sorts everything; np.argpartition only guarantees that the k largest end up at the end, which is faster on large arrays. On this data they disagreed. The strongest wine, row 652 at 14.9%, was picked by both, but seven wines are tied at 14.0%, so the second and third places are arbitrary, and the two methods chose different ones. When an interviewer asks for "the top 3", ask how ties should be handled. It is the same question as RANK versus ROW_NUMBER in SQL.
N9. Why are vectorised operations faster than loops?
A Python loop runs interpreter code for every element, while a vectorised operation runs a compiled loop over contiguous memory. Computing z-scores element by element was more than a thousand times slower than the one-line array version here, with an identical result. The exact factor changes from run to run, so quote the order of magnitude rather than the number.
N10. How do you make random results reproducible?
Create a generator with a seed, np.random.default_rng(42), and pass it around instead of using the global np.random functions (NumPy: random generator). Two generators with the same seed drew the same five rows. Without a seed, fresh entropy from the operating system makes every run different.
How to answer NumPy questions well
- Say the shapes before and after each operation.
- Name the data type, especially for integers and anything read from a file.
- Mention views whenever you slice and then modify.
- Ask about ties and missing values before writing top-N or summary code.
For the teaching version of these ideas, see the NumPy guide. Broader preparation is in Python interview questions: top 50 with answers, DataFrame questions in pandas interview questions, and algorithm-style tasks in Python coding interview questions and patterns.
What NumPy topics come up in data interviews?
What is the difference between a NumPy array and a Python list?
Does slicing a NumPy array copy the data?
What changed for interviews in NumPy 2?
NumPy is taught in the Python Programming course.
Sources
- Copies and views (NumPy documentation) — NumPy
- Broadcasting (NumPy documentation) — NumPy
- NEP 50: Promotion rules for Python scalars — NumPy
- Random Generator (NumPy documentation) — NumPy
- Wine Quality dataset (UCI Machine Learning Repository) — UCI Machine Learning Repository
GloryTecks Team
Training & Placement Faculty
The GloryTecks faculty team mentors learners across Data Science, AI and Data Engineering, with a focus on real-time projects and placement readiness in Hyderabad.
Want to master Interview Questions?
Join GloryTecks’ expert-led Python Programming training in Hyderabad with real-time projects and 100% placement support.
Related articles
Python Interview Questions for Data Roles
The plain-Python coding tasks data-analyst and data-engineer interviews use, without pandas: counting, deduplicating, grouping, streaming large files, flattening JSON, joining, and the bugs interviewers plant. Each has a worked solution and the follow-up questions to expect.
Data Science Interview Questions and Answers 2026
A data science interview is several interviews in one: statistics, machine learning, coding, product sense and a take-home. This guide maps each round with model answers, then works a churn take-home on real telecom data, including the checks that separate a strong submission from a high score.
AWS Interview Questions for Data Engineers
AWS interview questions for data engineers on S3, Glue, Athena, Redshift, Kinesis, Step Functions and security, each with the points a strong answer includes, the follow-up to expect, and three end-to-end scenario questions.