0% found this document useful (0 votes)
5 views18 pages

Numpy

This document provides a comprehensive guide to 30 interview questions and answers related to NumPy and Pandas, focusing on key concepts and functionalities. It covers topics such as array creation, vectorization, reshaping, broadcasting, and handling missing values, along with practical coding examples. The guide aims to prepare candidates for technical interviews in data analytics and data science roles.

Uploaded by

l8586095
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
5 views18 pages

Numpy

This document provides a comprehensive guide to 30 interview questions and answers related to NumPy and Pandas, focusing on key concepts and functionalities. It covers topics such as array creation, vectorization, reshaping, broadcasting, and handling missing values, along with practical coding examples. The guide aims to prepare candidates for technical interviews in data analytics and data science roles.

Uploaded by

l8586095
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd

NumPy & Pandas — 30 Interview Q&A

NumPy & Pandas


Complete Interview Q&A Guide
30 Questions with Full Answers & Code

SECTION A — NumPy Questions (Q1–Q15)


Q1. What is NumPy and why is it used in data analytics?

Answer:
NumPy (Numerical Python) is a library that provides fast, memory-efficient N-dimensional arrays and a large
collection of mathematical functions. It is used in data analytics because:
• It is 50–200x faster than Python lists for numerical operations
• It stores data in contiguous memory blocks with a fixed data type (unlike Python lists which store object
pointers)
• It is the foundation of Pandas, Scikit-learn, TensorFlow, and almost every data science library
• It enables vectorization — applying operations to entire arrays without writing loops

Q2. What is vectorization? Why is it faster than a for-loop?

Answer:
Vectorization means applying an operation to all elements of an array at once, delegating the work to
compiled C/Fortran code under the hood. There is no Python interpreter overhead per element.

import numpy as np

prices = [Link]([100, 200, 150, 300, 250])

# SLOW — Python loop (interpreter overhead every iteration):


result = []
for p in prices:
[Link](p * 1.18)

# FAST — Vectorized (runs in C, ~100x faster for large arrays):


result = prices * 1.18 # [118.0, 236.0, 177.0, 354.0, 295.0]

Interview tip: For 1 million elements, vectorized runs in ~2ms; a loop takes ~200ms. Always mention
the magnitude of the speedup.

Q3. How do you create NumPy arrays? Name at least 5 methods.

Answer:
NumPy & Pandas — 30 Interview Q&A

import numpy as np

[Link]([1, 2, 3]) # from a Python list


[Link]((3, 4)) # 3x4 matrix of zeros
[Link]((2, 3)) # 2x3 matrix of ones
[Link](0, 10, 2) # [0, 2, 4, 6, 8] — step-based
[Link](0, 1, 5) # [0.0, 0.25, 0.5, 0.75, 1.0] — evenly spaced
[Link](3, 3) # 3x3 random floats between 0 and 1
[Link](1, 100, (3,3))# 3x3 random integers 1–99
[Link](3) # 3x3 identity matrix
[Link]((2, 3), 7) # 2x3 matrix filled with 7

Interview tip: arange vs linspace: arange takes a step size; linspace takes the number of points.
Common follow-up question.

Q4. What are array attributes? Explain shape, ndim, size, dtype.

Answer:
a = [Link]([[1, 2, 3],
[4, 5, 6]])

[Link] # (2, 3) — 2 rows, 3 columns


[Link] # 2 — number of dimensions
[Link] # 6 — total number of elements
[Link] # int64 — data type of elements
[Link] # 8 — bytes per element

# Changing dtype:
[Link](np.float32) # convert to 32-bit float (saves memory)

Q5. Explain reshape. What rules must the new shape follow?

Answer:
reshape() returns a new view of the array with a different shape, without changing the data. The total
number of elements must stay the same.

a = [Link](12) # shape: (12,)

[Link](3, 4) # (3, 4) — 3 rows, 4 cols


[Link](2, 2, 3) # (2, 2, 3) — 3D
[Link](12, 1) # column vector
[Link](1, 12) # row vector

# Use -1 to let NumPy infer one dimension:


[Link](3, -1) # NumPy infers 4 columns -> (3, 4)
[Link](-1, 1) # column vector, NumPy infers 12 rows
NumPy & Pandas — 30 Interview Q&A

# Rule: product of new shape must equal product of original shape


# 3 * 4 == 2 * 2 * 3 == 12 ✓

Q6. What is broadcasting? Give a real-world example.

Answer:
Broadcasting allows NumPy to perform arithmetic on arrays of different shapes by virtually stretching the
smaller array to match the larger one — without copying data. The rules are:
1. Shapes are compared element-wise from the RIGHT
2. A dimension of size 1 can be stretched to match the other
3. If shapes are incompatible, a ValueError is raised

# Real-world: Normalize a dataset by subtracting column means


data = [Link]([[10, 20, 30],
[40, 50, 60],
[70, 80, 90]])
# shape: (3, 3)

means = [Link]([40, 50, 60]) # shape: (3,) = column means

centered = data - means # (3,3) - (3,) => broadcasts!


# means is stretched to (3,3) internally
# Result:
# [[-30, -30, -30],
# [ 0, 0, 0],
# [ 30, 30, 30]]

# Another example — add GST column-wise:


prices = [Link]([[100, 200], [300, 400]]) # (2,2)
tax = [Link]([0.05, 0.18]) # (2,) different rates
prices * (1 + tax) # each column multiplied by its rate

Interview tip: Draw the shape alignment on paper or whiteboard: (3,3) - (3,) — right-align the shapes
and show the stretch.

Q7. What is the difference between a view and a copy?

Answer:
A view shares the same memory buffer as the original array. A copy is an independent array in new
memory.

a = [Link]([10, 20, 30, 40, 50])

# VIEW — slicing returns a view:


b = a[1:4]
b[0] = 999
NumPy & Pandas — 30 Interview Q&A

print(a) # [10, 999, 30, 40, 50] <-- a was CHANGED!

# COPY — explicit copy is independent:


c = a[1:4].copy()
c[0] = 0
print(a) # unchanged

# How to check:
[Link] is a # True => b is a view of a
[Link] is None # True => c is a copy (no base)

# [Link]() also works:


d = [Link](a[1:4])

Interview tip: This is a classic trick question. The interviewer may write a[::2] += 1 and ask what
happens to a. Answer: a IS changed because slicing gives a view.

Q8. How do you index and slice a NumPy array? Include 2D examples.

Answer:
# 1D array:
a = [Link]([10, 20, 30, 40, 50])
a[0] # 10 — first element
a[-1] # 50 — last element
a[1:4] # [20, 30, 40]
a[::2] # [10, 30, 50] — every 2nd element
a[::-1] # [50, 40, 30, 20, 10] — reverse

# 2D array:
m = [Link](9).reshape(3, 3)
# [[0, 1, 2],
# [3, 4, 5],
# [6, 7, 8]]

m[1, 2] # 5 — row 1, col 2


m[0, :] # [0, 1, 2] — entire row 0
m[:, 1] # [1, 4, 7] — entire column 1
m[0:2, 1:3] # [[1,2],[4,5]] — submatrix

# Boolean / fancy indexing:


a[a > 25] # [30, 40, 50]
a[(a > 15) & (a < 45)] # [20, 30, 40]
a[[0, 2, 4]] # [10, 30, 50] — fancy indexing

Q9. What are the main statistical and mathematical functions in NumPy?

Answer:
a = [Link]([4, 7, 2, 9, 1, 5, 8, 3, 6])
NumPy & Pandas — 30 Interview Q&A

# Basic statistics:
[Link](a) # 5.0 — average
[Link](a) # 5.0 — middle value
[Link](a) # standard deviation
[Link](a) # variance
[Link](a) # 1
[Link](a) # 9
[Link](a) # 45
[Link](a) # [4,11,13,22,23,28,36,39,45] — running total
[Link](a) # 4 — INDEX of minimum
[Link](a) # 3 — INDEX of maximum
[Link](a, 75) # 75th percentile

# On 2D arrays — axis matters:


m = [Link]([[1,2,3],[4,5,6]])
[Link](m, axis=0) # [5,7,9] — sum DOWN columns
[Link](m, axis=1) # [6,15] — sum ACROSS rows
[Link](m, axis=0) # [2.5,3.5,4.5]

# Math functions:
[Link](a) # square root of each element
[Link](a) # natural log
[Link](a) # absolute value
[Link](a, 2) # round to 2 decimals

Q10. How do you sort a NumPy array? What is argsort?

Answer:
a = [Link]([30, 10, 50, 20, 40])

[Link](a) # [10, 20, 30, 40, 50] — returns sorted copy


[Link]() # sorts a IN PLACE (modifies original)
[Link](a)[::-1] # descending: [50, 40, 30, 20, 10]

# argsort returns INDICES that would sort the array:


idx = [Link](a) # [1, 3, 0, 4, 2]
a[idx] # [10, 20, 30, 40, 50] — sorted via indices

# Real use case: sort one array by another:


scores = [Link]([85, 92, 78, 95])
names = [Link](['Alice','Bob','Carol','Dave'])
sorted_idx = [Link](scores)[::-1]
names[sorted_idx] # ['Dave','Bob','Alice','Carol'] — ranked

# Sort 2D array by a column:


m = [Link]([[3,1],[1,4],[2,2]])
m[m[:,0].argsort()] # sort rows by first column

Q11. What is [Link]? How is it used?


NumPy & Pandas — 30 Interview Q&A

Answer:
[Link](condition, value_if_true, value_if_false) is a vectorized if-else that works element-wise on arrays. It
is much faster than applying a lambda with a loop.

scores = [Link]([45, 72, 88, 55, 91, 63])

# Assign pass/fail:
result = [Link](scores >= 60, 'Pass', 'Fail')
# ['Fail','Pass','Pass','Fail','Pass','Pass']

# Three-tier grading:
grades = [Link](scores >= 80, 'A',
[Link](scores >= 60, 'B', 'C'))
# ['C','B','A','C','A','B']

# Replace negative values with 0 (ReLU activation):


data = [Link]([-3, 5, -1, 8, -2, 4])
relu = [Link](data > 0, data, 0)
# [0, 5, 0, 8, 0, 4]

# With just a condition (returns indices where True):


[Link](scores > 70) # (array([1, 2, 4]),)

Q12. How do you stack and split arrays?

Answer:
a = [Link]([1, 2, 3])
b = [Link]([4, 5, 6])

# Stack vertically (row-wise):


[Link]([a, b]) # [[1,2,3],[4,5,6]] — shape (2,3)

# Stack horizontally (column-wise):


[Link]([a, b]) # [1,2,3,4,5,6] — shape (6,)

# Stack as columns in a 2D array:


np.column_stack([a, b]) # [[1,4],[2,5],[3,6]] — shape (3,2)

# Concatenate along an axis:


[Link]([a, b]) # axis=0 default
[Link]([a[:,None], b[:,None]], axis=1) # side by side

# Split an array:
c = [Link](12)
[Link](c, 3) # 3 equal parts: [0-3], [4-7], [8-11]
np.array_split(c, 5) # 5 parts (handles uneven split)

Q13. How do you handle missing values (NaN) in NumPy?


NumPy & Pandas — 30 Interview Q&A

Answer:
NaN (Not a Number) is a special float value representing missing data. Standard functions like [Link]()
return NaN if any element is NaN. Use nan-safe functions instead.

a = [Link]([1.0, 2.0, [Link], 4.0, [Link], 6.0])

[Link](a) # [F, F, T, F, T, F]
[Link]([Link](a)) # 2 — count of NaN values

[Link](a) # nan (poisoned by NaN)


[Link](a) # 3.25 — ignores NaN
[Link](a) # 13.0
[Link](a) # 6.0
[Link](a) # standard deviation ignoring NaN

# Remove NaN values:


clean = a[~[Link](a)] # [1.0, 2.0, 4.0, 6.0]

# Replace NaN with mean:


mean_val = [Link](a)
a[[Link](a)] = mean_val # impute with mean in-place

Q14. What is the difference between [Link], [Link], and *?

Answer:
a = [Link]([[1, 2], [3, 4]])
b = [Link]([[5, 6], [7, 8]])

# * and [Link] — element-wise multiplication:


a * b # [[5,12],[21,32]]
[Link](a, b) # same result

# [Link] — matrix multiplication (dot product):


[Link](a, b) # [[1*5+2*7, 1*6+2*8], = [[19,22],[43,50]]
# [3*5+4*7, 3*6+4*8]]
a @ b # same as [Link] — @ is the matmul operator

# For 1D arrays:
x = [Link]([1, 2, 3])
y = [Link]([4, 5, 6])
[Link](x, y) # 1*4 + 2*5 + 3*6 = 32 (scalar dot product)
x * y # [4, 10, 18] (element-wise)

Interview tip: Use @ for matrix multiplication in modern Python. Use * when you want element-wise.
This distinction is tested in ML contexts.

Q15. How do you improve NumPy performance for large arrays?


NumPy & Pandas — 30 Interview Q&A

Answer:
Key optimization strategies:
# 1. Use the right dtype (float32 uses half the memory of float64):
a = [Link]([1.0, 2.0, 3.0], dtype=np.float32)

# 2. Use in-place operations to avoid extra memory allocation:


a += 1 # better than a = a + 1
[Link](a, 2, out=a)

# 3. Avoid unnecessary copies — use views:


b = a[::2] # view, not a copy

# 4. Use vectorized functions instead of loops:


[Link](a) # not [[Link](x) for x in a]

# 5. Use [Link] for complex multi-dimensional operations:


[Link]('ij,jk->ik', A, B) # matrix multiply, optimized path

# 6. Memory-mapped files for arrays too large for RAM:


fp = [Link]('[Link]', dtype='float32', mode='r', shape=(1000000,))

# 7. Use numba for unavoidable Python loops:


# from numba import jit
# @jit(nopython=True)
# def fast_loop(a): ...

SECTION B — Pandas Questions (Q16–Q30)


Q16. What is a DataFrame and a Series? How are they related?

Answer:
A Series is a one-dimensional labeled array — essentially a single column with an index. A DataFrame is a
two-dimensional table made of multiple Series sharing the same index.
import pandas as pd

# Series:
s = [Link]([10, 20, 30], index=['a','b','c'])
s['b'] # 20

# DataFrame:
df = [Link]({
'name': ['Alice','Bob','Carol'],
'age': [25, 30, 28],
'salary': [50000, 60000, 55000]
})

# Each column IS a Series:


type(df['salary']) # <class '[Link]'>
NumPy & Pandas — 30 Interview Q&A

# Pandas is built on NumPy:


df['salary'].values # numpy array: [50000, 60000, 55000]

Q17. What is the difference between loc and iloc?

Answer:
df = [Link]({
'name': ['Alice','Bob','Carol','Dave'],
'salary': [50000, 60000, 55000, 70000]
}, index=[10, 20, 30, 40]) # custom index labels

# loc — label-based (uses the INDEX VALUE):


[Link][20] # row with label 20 -> Bob
[Link][20, 'salary'] # 60000
[Link][10:30] # rows labeled 10, 20, 30 (INCLUSIVE)

# iloc — position-based (uses INTEGER POSITION):


[Link][1] # 2nd row (position 1) -> Bob
[Link][1, 1] # row 1, col 1 -> 60000
[Link][0:3] # positions 0,1,2 (exclusive end)

# Key difference:
# With default integer index (0,1,2...) loc and iloc behave the same.
# With custom index (like 10,20,30 above) they differ:
# [Link][1] -> KeyError (no label '1')
# [Link][1] -> works (position 1 = Bob)

Interview tip: Common trick: if the index is [10,20,30], [Link][1] fails but [Link][1] works. Know the
difference.

Q18. How do you filter rows in a DataFrame?

Answer:
df = pd.read_csv('[Link]')

# Single condition:
df[df['salary'] > 50000]

# Multiple conditions — use & (AND) and | (OR):


df[(df['age'] > 25) & (df['department'] == 'Engineering')]
df[(df['city'] == 'Mumbai') | (df['city'] == 'Delhi')]

# Filter by list of values:


df[df['city'].isin(['Mumbai', 'Delhi', 'Pune'])]

# Exclude values:
df[~df['city'].isin(['Chennai'])] # ~ is NOT
NumPy & Pandas — 30 Interview Q&A

# String filters:
df[df['name'].[Link]('A')]
df[df['email'].[Link]('@gmail')]

# Filter by null / non-null:


df[df['salary'].isnull()]
df[df['salary'].notnull()]

# query() method (SQL-like, readable):


[Link]('salary > 50000 and age < 35')

Q19. How do you handle missing data in Pandas?

Answer:
# Step 1: Detect missing values:
[Link]().sum() # count nulls per column
[Link]().sum() / len(df) * 100 # % missing per column
[Link]().any(axis=1) # rows with ANY null

# Step 2: Drop nulls:


[Link]() # drop rows with any null
[Link](subset=['salary']) # drop only if salary is null
[Link](thresh=3) # keep rows with at least 3 non-null
[Link](how='all') # drop only if ALL values are null

# Step 3: Fill nulls:


df['salary'].fillna(0) # fixed value
df['salary'].fillna(df['salary'].mean()) # mean imputation
df['salary'].fillna(df['salary'].median()) # median (better for skewed)
df['city'].fillna('Unknown') # for categorical columns
df['price'].fillna(method='ffill') # forward fill (time series)
df['price'].fillna(method='bfill') # backward fill

# Apply in-place:
[Link]({'salary': df['salary'].mean(),
'city': 'Unknown'}, inplace=True)

Interview tip: Always explain WHY you chose the strategy. 'I used median instead of mean because
the salary column has outliers that would skew the mean.'

Q20. How does GroupBy work? Walk through the split-apply-combine pattern.

Answer:
GroupBy follows three steps: Split the data into groups based on a key, Apply a function to each group
independently, Combine the results back into a single structure.

df = [Link]({
NumPy & Pandas — 30 Interview Q&A

'dept': ['Eng','Eng','Sales','Sales','HR'],
'salary': [80000, 90000, 50000, 55000, 45000],
'age': [28, 32, 26, 30, 35]
})

# Basic aggregation:
[Link]('dept')['salary'].mean()
# dept
# Eng 85000.0
# HR 45000.0
# Sales 52500.0

# Multiple aggregations:
[Link]('dept').agg(
avg_salary=('salary', 'mean'),
max_salary=('salary', 'max'),
headcount= ('salary', 'count')
)

# Group by multiple columns:


[Link](['dept','city'])['revenue'].sum().reset_index()

# Apply a custom function:


[Link]('dept')['salary'].apply(lambda x: [Link]() - [Link]())

# Transform (keeps original index — great for adding group stats):


df['dept_avg'] = [Link]('dept')['salary'].transform('mean')

Q21. How do you merge/join two DataFrames?

Answer:
orders =
[Link]({'order_id':[1,2,3],'cust_id':[101,102,101],'amount':[500,300,700]})
customers = [Link]({'id':[101,102,103],'name':['Alice','Bob','Carol']})

# INNER JOIN — only rows with matches in both:


[Link](orders, customers, left_on='cust_id', right_on='id')

# LEFT JOIN — all orders, even without a customer match:


[Link](orders, customers, left_on='cust_id', right_on='id', how='left')

# RIGHT JOIN — all customers, even without orders:


[Link](orders, customers, left_on='cust_id', right_on='id', how='right')

# OUTER JOIN — all rows from both:


[Link](orders, customers, left_on='cust_id', right_on='id', how='outer')

# Join on same column name:


[Link](df1, df2, on='customer_id')

# Stack rows (union):


[Link]([df_jan, df_feb, df_mar], ignore_index=True)
NumPy & Pandas — 30 Interview Q&A

Join type SQL equivalent Result


inner INNER JOIN Only matching rows
left LEFT JOIN All from left + matches
right RIGHT JOIN All from right + matches
outer FULL OUTER JOIN All rows from both

Q22. How do you apply a function to a column or row?

Answer:
df =
[Link]({'name':['alice','BOB'],'salary':[50000,60000],'score':[75,88]})

# apply() — runs a function on each element (Series) or row/col (DataFrame):


df['salary'].apply(lambda x: x * 1.18) # add GST
df['name'].apply([Link]) # Title Case

# Vectorized string methods (faster than apply for strings):


df['name'].[Link]()
df['name'].[Link]()
df['name'].[Link]('bob', 'Bob')

# map() — element-wise on a Series (good for mappings):


grade_map = {75:'C', 88:'B'}
df['score'].map(grade_map)

# apply on whole DataFrame rows (axis=1):


[Link](lambda row: row['salary'] * 1.2 if row['score'] > 80 else
row['salary'], axis=1)

# [Link] is faster for conditional column creation:


import numpy as np
df['bonus'] = [Link](df['score'] > 80, df['salary']*0.2, df['salary']*0.1)

Q23. How do you sort a DataFrame and get the top N rows?

Answer:
# Sort by one column:
df.sort_values('salary', ascending=False)

# Sort by multiple columns:


df.sort_values(['department','salary'], ascending=[True, False])

# Top 5 highest salaries:


[Link](5, 'salary')

# Bottom 5:
NumPy & Pandas — 30 Interview Q&A

[Link](5, 'salary')

# Top N per group (top earner per department):


df.sort_values('salary', ascending=False).groupby('department').head(1)

# Reset index after sorting:


df.sort_values('salary', ascending=False).reset_index(drop=True)

Q24. How do you add, rename, and drop columns?

Answer:
# Add a new column:
df['salary_gst'] = df['salary'] * 1.18
df['full_name'] = df['first'] + ' ' + df['last']

# Rename columns:
[Link](columns={'salary':'annual_salary', 'age':'years'}, inplace=True)

# Drop columns:
[Link](columns=['unwanted_col'], inplace=True)
[Link](columns=['col1','col2'], inplace=True)

# Drop rows:
[Link](index=[0, 2], inplace=True) # drop rows at position 0 and 2

# Reorder columns:
df = df[['name','department','salary','age']]

# Convert data types:


df['salary'] = df['salary'].astype(float)
df['date'] = pd.to_datetime(df['date'])
df['dept'] = df['dept'].astype('category') # saves memory

Q25. How do you remove duplicates?

Answer:
# Check for duplicates:
[Link]().sum() # total duplicate rows
[Link](subset=['email']).sum() # duplicate emails

# Remove duplicate rows:


df.drop_duplicates() # keep first occurrence
df.drop_duplicates(keep='last') # keep last occurrence
df.drop_duplicates(keep=False) # remove ALL duplicates

# Deduplicate by specific columns:


df.drop_duplicates(subset=['email', 'phone'])

# View which rows are duplicated:


NumPy & Pandas — 30 Interview Q&A

df[[Link](keep=False)] # show all duplicate rows

Q26. How do you work with dates and times in Pandas?

Answer:
df['date'] = pd.to_datetime(df['date']) # parse string to datetime

# Extract date parts:


df['year'] = df['date'].[Link]
df['month'] = df['date'].[Link]
df['day'] = df['date'].[Link]
df['weekday'] = df['date'].dt.day_name() # 'Monday', 'Tuesday'...
df['quarter'] = df['date'].[Link]

# Filter by date range:


df[df['date'] >= '2024-01-01']
df[(df['date'] >= '2024-01-01') & (df['date'] <= '2024-06-30')]

# Date arithmetic:
df['days_since'] = ([Link]() - df['date']).[Link]

# Resample time series (e.g., daily data to monthly totals):


df.set_index('date').resample('M')['revenue'].sum()

Q27. What is the difference between apply, map, and applymap/map for DataFrames?

Answer:
Method Works on Use for Example
apply() Series or DataFrame Custom aggregation or df['col'].apply(func)
row/col logic
map() Series only Element-wise [Link]({'a':1,'b':2})
transform or mapping
dict
map() on DF* DataFrame Element-wise on whole [Link]([Link])
DF (was applymap)

Note: In Pandas 2.1+, applymap() was renamed to map() on DataFrames. For older code you may see
applymap().

s = [Link]([1, 2, 3, 4])

[Link](lambda x: x**2) # [1, 4, 9, 16] — Series map


[Link](lambda x: x**2) # same for simple case

# apply on groups (more powerful):


NumPy & Pandas — 30 Interview Q&A

[Link]('dept')['salary'].apply(lambda x: x - [Link]()) # demean

# map with dict to replace values:


[Link]({1:'low', 2:'mid', 3:'high', 4:'high'}) # label encoding

Q28. How would you clean a messy real-world dataset? Walk through your process.

Answer:
This is a process question. Walk through these steps in order:
# Step 1 — Understand the data:
[Link] # how many rows/cols
[Link]() # dtypes and null counts
[Link]() # stats for numeric cols
[Link](10) # eyeball the data

# Step 2 — Handle missing values:


[Link]().sum() # identify nulls
# (choose drop/fill strategy per column based on context)

# Step 3 — Fix data types:


df['date'] = pd.to_datetime(df['date'])
df['salary'] = pd.to_numeric(df['salary'], errors='coerce')
df['dept'] = df['dept'].astype('category')

# Step 4 — Remove duplicates:


df.drop_duplicates(inplace=True)

# Step 5 — Standardize strings:


df['city'] = df['city'].[Link]().[Link]()
df['email'] = df['email'].[Link]()

# Step 6 — Handle outliers:


Q1 = df['salary'].quantile(0.25)
Q3 = df['salary'].quantile(0.75)
IQR = Q3 - Q1
df = df[~((df['salary'] < Q1 - 1.5*IQR) | (df['salary'] > Q3 + 1.5*IQR))]

# Step 7 — Validate:
assert df['salary'].min() >= 0, 'Negative salaries found!'
assert [Link]().sum().sum() == 0, 'Still have nulls!'

Interview tip: Mention that the strategy for each step depends on domain context — interviewers love
seeing that you think beyond just code.

Q29. How do you use pivot tables and crosstabs?

Answer:
df = [Link]({
NumPy & Pandas — 30 Interview Q&A

'region': ['North','North','South','South'],
'product': ['A','B','A','B'],
'sales': [100, 200, 150, 250]
})

# Pivot table — like Excel pivot:


df.pivot_table(
values='sales',
index='region',
columns='product',
aggfunc='sum',
fill_value=0
)
# product A B
# region
# North 100 200
# South 150 250

# Crosstab — frequency table between two categorical columns:


[Link](df['region'], df['product'])

# Crosstab with values:


[Link](df['region'], df['product'],
values=df['sales'], aggfunc='sum')

# melt() — unpivot (wide to long format):


[Link](id_vars=['region'], value_vars=['A_sales','B_sales'],
var_name='product', value_name='sales')

Q30. How do you improve Pandas performance for large datasets?

Answer:
Key performance strategies when data is large:
# 1. Read only needed columns (reduces I/O and RAM):
df = pd.read_csv('[Link]', usecols=['id','salary','dept'])

# 2. Use efficient dtypes:


df = pd.read_csv('[Link]', dtype={'salary': 'float32',
'dept': 'category'})
df['dept'] = df['dept'].astype('category') # after loading

# 3. Filter early — reduce size before operations:


df = df[df['year'] == 2024]

# 4. Avoid apply() for simple ops — use vectorized instead:


df['gst'] = df['price'] * 1.18 # fast
df['gst'] = df['price'].apply(lambda x: x * 1.18) # slow

# 5. Use [Link] instead of apply for conditions:


df['grade'] = [Link](df['score'] >= 60, 'Pass', 'Fail')

# 6. Chunked reading for files too large for RAM:


NumPy & Pandas — 30 Interview Q&A

chunks = []
for chunk in pd.read_csv('[Link]', chunksize=100000):
[Link](chunk[chunk['status'] == 'active'])
df = [Link](chunks)

# 7. Use Parquet instead of CSV (columnar, compressed, faster):


df.to_parquet('[Link]')
df = pd.read_parquet('[Link]', columns=['id','salary'])

# 8. For truly huge data, switch to Dask (same API as Pandas):


import [Link] as dd
ddf = dd.read_csv('[Link]')
[Link]('dept')['salary'].mean().compute()

Interview tip: Profile first: use %timeit in Jupyter or cProfile. Optimize the bottleneck, not everything.
Interviewers respect this mindset.

Quick Reference — All 30 Questions at a Glance


Q# Topic Key point to remember
1 What is NumPy Fast N-dim arrays, C-speed, foundation of data
science
2 Vectorization C-code, no Python loop overhead, ~100x faster
3 Array creation array, zeros, ones, arange, linspace, random
4 Array attributes shape, ndim, size, dtype
5 Reshape Total elements must stay same; use -1 to infer
6 Broadcasting Align from right, stretch size-1 dims; no copies
7 View vs Copy Slice = view (shared memory); .copy() =
independent
8 Indexing/slicing a[1:3], a[a>5], a[[0,2,4]], m[:,1]
9 Statistics mean, std, argmax, nanmean; axis=0 cols,
axis=1 rows
10 Sorting [Link], argsort returns indices
11 [Link] Vectorized if-else: where(cond, true_val,
false_val)
12 Stack/Split vstack, hstack, concatenate, split
13 NaN handling [Link], nanmean, a[~[Link](a)]
14 dot vs * * = element-wise; [Link] / @ = matrix multiply
15 Performance float32, in-place +=, views, einsum, numba
16 Series vs DataFrame Series = 1 column; DF = multiple Series with
same index
NumPy & Pandas — 30 Interview Q&A

17 loc vs iloc loc = label; iloc = integer position


18 Filtering rows df[cond], &/|, isin(), query()
19 Missing data isnull, dropna, fillna(mean/median/ffill)
20 GroupBy Split-apply-combine; agg, transform
21 Merge/Join [Link]; how=inner/left/right/outer
22 apply/map apply=rows/cols; map=element-wise;
[Link]=fastest
23 Sort/top-N sort_values, nlargest, nsmallest
24 Column ops assign, rename, drop, astype
25 Duplicates duplicated, drop_duplicates, keep=first/last/False
26 Dates to_datetime, [Link]/month, resample
27 apply vs map apply=flexible; map=element/dict;
map(DF)=elementwise
28 Data cleaning info>nulls>dtypes>dupes>strings>outliers>assert
29 Pivot tables pivot_table, crosstab, melt
30 Performance usecols, category dtype, vectorize, parquet,
Dask

You might also like