■ PYTHON FOR DATA
ANALYSIS
MASTER SOURCE — Complete Concepts, Logic Patterns & Practice
Questions
Prepared for: Aman | MDU BBA Program | Python + Data Analysis Track
# Chapter / Concept Group Topics Inside
1 Python Control Flow if, elif, else, nested if, logical ops
2 Loops for, while, break, continue, pass, nested, range
3 Functions (def) def, return, args, *args, **kwargs, scope
4 Lambda & Functional Tools lambda, map, filter, reduce
5 Recursion factorial, fibonacci, recursive patterns
6 Data Structures list, tuple, set, dict, string
7 Error & Exception Handling try/except, raise, finally, custom exceptions
8 NumPy arrays, indexing, ops, broadcasting, random
9 Pandas Series, DataFrame, loc/iloc, filter, sort
10 Data Cleaning missing values, duplicates, outliers, dtypes
11 Data Manipulation groupby, merge, concat, pivot, apply
12 EDA describe, corr, value_counts, crosstab
13 Visualization Matplotlib, Seaborn — all chart types
14 Statistics mean/std, distributions, hypothesis testing
15 Intro to sklearn / ML regression, classification, accuracy
Python for Data Analysis — Master Source Page 1
if / elif / else / nested if / logical
Chapter 1: Control Flow operators
Control flow statements decide WHICH block of code runs based on conditions. They are the brain of any
program — without them, code would run top-to-bottom with no decisions, no branching, no intelligence.
1.1 if Statement
The simplest decision: if a condition is True, run the indented block.
if condition:
# runs only when condition is True
statement
# Example
age = 20
if age >= 18:
print("You are an adult")
■ Python uses INDENTATION (4 spaces) instead of braces {}. Wrong indentation = IndentationError.
1.2 if-else Statement
Two branches: if condition is True → first block. If False → else block.
if condition:
# True branch
else:
# False branch
# Example
marks = 45
if marks >= 50:
print("Pass")
else:
print("Fail")
1.3 if-elif-else (Multiple Conditions)
When you have MORE than 2 outcomes, use elif. Python checks each condition top-down and stops at the
FIRST True one.
Python for Data Analysis — Master Source Page 2
if condition1:
block1
elif condition2:
block2
elif condition3:
block3
else:
default_block
# Example: Grade system
marks = 75
if marks >= 90:
grade = "A+"
elif marks >= 80:
grade = "A"
elif marks >= 70:
grade = "B"
elif marks >= 60:
grade = "C"
elif marks >= 50:
grade = "D"
else:
grade = "F"
print(grade) # B
1.4 Nested if
An if statement inside another if statement. Used when conditions depend on each other.
age = 25
has_id = True
if age >= 18:
if has_id:
print("Entry allowed")
else:
print("Show your ID")
else:
print("Minors not allowed")
■ Avoid nesting more than 3 levels deep — use logical operators instead.
1.5 Logical Operators: and / or / not
Python for Data Analysis — Master Source Page 3
# and — both must be True
if age >= 18 and has_id:
print("Access granted")
# or — at least one must be True
if day == "Saturday" or day == "Sunday":
print("Weekend!")
# not — reverses True/False
if not is_logged_in:
print("Please login")
# Combining
if age >= 18 and (has_id or is_member):
print("Welcome")
1.6 Ternary (One-line if-else)
result = "Pass" if marks >= 50 else "Fail"
# Same as:
# if marks >= 50: result = "Pass"
# else: result = "Fail"
# In print
print("Even" if num % 2 == 0 else "Odd")
1.7 Comparison & Membership Operators
# Comparison
== != < > <= >=
# Membership
x in [1,2,3] # True if x is in list
x not in [1,2,3] # True if x NOT in list
# Identity
x is None # checks same object
x is not None
# Chained comparison
if 0 <= score <= 100:
print("Valid score")
PRACTICE QUESTIONS — Control Flow
Q1. Write a program to check if a number is positive, negative, or zero.
→ Use if-elif-else with three branches.
num = int(input("Enter number: "))
if num > 0:
print("Positive")
elif num < 0:
print("Negative")
else:
print("Zero")
Python for Data Analysis — Master Source Page 4
Q2. Check if a person is eligible to vote (age >= 18 AND citizen == True).
→ Use 'and' logical operator.
age = 20
citizen = True
if age >= 18 and citizen:
print("Eligible to vote")
else:
print("Not eligible")
Q3. Write a grade calculator: 90+=A+, 80+=A, 70+=B, 60+=C, 50+=D, else F.
→ Use full if-elif-else chain.
marks = int(input("Marks: "))
if marks >= 90: grade = "A+"
elif marks >= 80: grade = "A"
elif marks >= 70: grade = "B"
elif marks >= 60: grade = "C"
elif marks >= 50: grade = "D"
else: grade = "F"
print("Grade:", grade)
Q4. Find the maximum of three numbers using nested if.
→ Compare a with b, then winner with c.
a, b, c = 10, 25, 15
if a > b:
if a > c: print(a)
else: print(c)
else:
if b > c: print(b)
else: print(c)
Q5. Check if a year is a leap year.
→ Divisible by 4 AND (not 100 OR divisible by 400).
year = int(input("Year: "))
if (year % 4 == 0 and year % 100 != 0) or year % 400 == 0:
print("Leap year")
else:
print("Not a leap year")
Q6. Check if a number is divisible by both 3 and 5.
→ Use 'and' operator.
n = int(input())
print("Yes" if n % 3 == 0 and n % 5 == 0 else "No")
Q7. Given a temperature, print 'Hot' if >35, 'Warm' if 20-35, 'Cold' if <20.
→ Three conditions with elif.
temp = float(input("Temp: "))
if temp > 35: print("Hot")
elif temp >= 20: print("Warm")
else: print("Cold")
Q8. Using 'in' operator, check if a character is a vowel.
→ Use membership operator.
ch = input("Enter a character: ").lower()
if ch in "aeiou":
print("Vowel")
else:
print("Not a vowel")
Python for Data Analysis — Master Source Page 5
Q9. Ternary: print the absolute value of a number without abs().
→ One-line if-else.
n = int(input())
print(n if n >= 0 else -n)
Q10. Write login checker: username='admin', password='1234'.
→ Use 'and' with ==.
u = input("Username: ")
p = input("Password: ")
if u == "admin" and p == "1234":
print("Login successful")
else:
print("Invalid credentials")
Q11. Check if a number is between 1 and 100 (inclusive) using chained comparison.
→ Use 1 <= n <= 100.
n = int(input())
print("In range" if 1 <= n <= 100 else "Out of range")
Q12. Traffic light system: Red=Stop, Yellow=Slow, Green=Go.
→ elif chain.
light = input("Light color: ").lower()
if light == "red": print("Stop")
elif light == "yellow":print("Slow")
elif light == "green": print("Go")
else: print("Invalid")
Q13. Calculate electricity bill: 0-100 units=Rs.5/unit, 101-300=Rs.7, >300=Rs.10.
→ Use elif with different rates.
units = int(input("Units: "))
if units <= 100:
bill = units * 5
elif units <= 300:
bill = 100*5 + (units-100)*7
else:
bill = 100*5 + 200*7 + (units-300)*10
print("Bill: Rs.", bill)
Q14. Check if a string is empty using 'not'.
→ 'not' on empty string is True.
s = input("Enter string: ")
if not s:
print("Empty string")
else:
print("Not empty:", s)
Q15. BMI calculator: <18.5=Underweight, 18.5-24.9=Normal, 25-29.9=Overweight, 30+=Obese.
→ Four elif branches.
h = float(input("Height(m): "))
w = float(input("Weight(kg): "))
bmi = w / (h**2)
if bmi < 18.5: print("Underweight")
elif bmi < 25: print("Normal")
elif bmi < 30: print("Overweight")
else: print("Obese")
Python for Data Analysis — Master Source Page 6
for / while / break / continue /
Chapter 2: Loops pass / nested / range
Loops let you repeat code automatically. Instead of writing the same line 100 times, you write it once inside a
loop. Python has two loop types: for (known iterations) and while (condition-based).
2.1 for Loop
for variable in iterable:
body
# Examples
for i in range(5): print(i) # 0 1 2 3 4
for ch in "Python": print(ch) # P y t h o n
for item in [1,2,3]: print(item)
for k,v in [Link](): print(k,v) # dict iteration
for i, val in enumerate(lst): print(i, val) # with index
for a, b in zip(l1, l2): print(a, b) # parallel
2.2 range() Function
range(stop) # 0 to stop-1
range(start, stop) # start to stop-1
range(start, stop, step) # with step
range(5) → 0,1,2,3,4
range(1,6) → 1,2,3,4,5
range(0,10,2) → 0,2,4,6,8
range(10,0,-1) → 10,9,8,...,1 (reverse)
2.3 while Loop
while condition:
body
# must update condition to avoid infinite loop
i = 0
while i < 5:
print(i)
i += 1 # MUST update i
# While True + break pattern
while True:
cmd = input("Enter command (quit to exit): ")
if cmd == "quit":
break
print("You entered:", cmd)
2.4 break — Exit Loop Early
Python for Data Analysis — Master Source Page 7
# Stop as soon as found
numbers = [1,5,3,8,2,9]
for n in numbers:
if n == 8:
print("Found 8!")
break # exits immediately
# Useful: first match, login attempts
attempts = 0
while attempts < 3:
pwd = input("Password: ")
if pwd == "secret":
print("Correct!")
break
attempts += 1
2.5 continue — Skip One Iteration
# Skip even numbers, print only odd
for i in range(10):
if i % 2 == 0:
continue # go to next iteration
print(i) # 1 3 5 7 9
# Skip None values
data = [1, None, 3, None, 5]
for d in data:
if d is None:
continue
print(d)
2.6 pass — Do Nothing (Placeholder)
for i in range(5):
pass # valid empty loop
def todo_function():
pass # function stub, to be filled later
if condition:
pass # placeholder, no error
2.7 Nested Loops
Python for Data Analysis — Master Source Page 8
# Multiplication table
for i in range(1,4):
for j in range(1,4):
print(i*j, end=" ")
print()
# Pattern printing
for i in range(1,6):
for j in range(i):
print("*", end="")
print()
# Output:
# *
# **
# ***
# ****
# *****
# 2D list (matrix) traversal
matrix = [[1,2,3],[4,5,6],[7,8,9]]
for row in matrix:
for val in row:
print(val, end=" ")
print()
2.8 Loop with else
# else runs if loop completed WITHOUT break
for i in range(2, n):
if n % i == 0:
print("Not prime")
break
else:
print("Prime!") # only if no break occurred
PRACTICE QUESTIONS — Loops
Q1. Print numbers 1 to 10 using for loop.
→ Use range(1,11).
for i in range(1,11):
print(i)
Q2. Print multiplication table of any number n.
→ Nested or single loop with range(1,11).
n = int(input("Enter number: "))
for i in range(1,11):
print(f"{n} x {i} = {n*i}")
Q3. Find sum of all numbers from 1 to 100.
→ Accumulate in variable.
total = sum(range(1,101))
print(total) # 5050
Q4. Print all even numbers from 1 to 50.
→ Use range with step 2, or if i%2==0.
for i in range(2,51,2):
print(i)
Python for Data Analysis — Master Source Page 9
Q5. Reverse a string using a loop.
→ Iterate string in reverse.
s = "Python"
rev = ""
for ch in s:
rev = ch + rev
print(rev) # nohtyP
Q6. Count vowels in a string.
→ Check each char against 'aeiou'.
s = "Hello World"
count = 0
for ch in [Link]():
if ch in "aeiou":
count += 1
print("Vowels:", count)
Q7. Print star pyramid pattern (5 rows).
→ Nested loop.
for i in range(1,6):
for j in range(i):
print("*", end="")
print()
Q8. Find factorial of n using while loop.
→ Multiply 1..n.
n = int(input())
fact = 1
i = 1
while i <= n:
fact *= i
i += 1
print(fact)
Q9. Print Fibonacci series up to n terms.
→ Add previous two numbers.
n = int(input("Terms: "))
a, b = 0, 1
for _ in range(n):
print(a, end=" ")
a, b = b, a+b
Q10. Check if a number is prime.
→ loop from 2 to sqrt(n).
import math
n = int(input())
is_prime = True
for i in range(2, int([Link](n))+1):
if n % i == 0:
is_prime = False
break
print("Prime" if is_prime else "Not prime")
Q11. Skip multiples of 3 while printing 1-20.
→ Use continue.
for i in range(1,21):
if i % 3 == 0:
continue
print(i)
Python for Data Analysis — Master Source Page 10
Q12. Sum of digits of a number.
→ Extract digits with % 10.
n = int(input())
s = 0
while n > 0:
s += n % 10
n //= 10
print("Sum of digits:", s)
Q13. Print all elements of a 2D list using nested for.
→ Row by row.
matrix = [[1,2,3],[4,5,6],[7,8,9]]
for row in matrix:
for val in row:
print(val, end=" ")
print()
Q14. Find largest number in a list without max().
→ Compare each element.
lst = [3,9,1,7,4]
largest = lst[0]
for n in lst:
if n > largest:
largest = n
print("Largest:", largest)
Q15. Count even and odd numbers in a list.
→ Two counters.
lst = [1,2,3,4,5,6,7,8]
even = odd = 0
for n in lst:
if n % 2 == 0: even += 1
else: odd += 1
print(f"Even: {even}, Odd: {odd}")
Python for Data Analysis — Master Source Page 11
def, return, args, *args,
Chapter 3: Functions (def) **kwargs, scope, docstring
A function is a reusable block of code with a name. Define it once, call it anywhere. Functions make code
modular, readable, and maintainable. In Python, every function is defined with 'def'.
3.1 Defining and Calling a Function
def function_name(parameters):
"""Docstring — describe what it does"""
body
return value # optional
# Example
def greet(name):
"""Returns greeting message"""
return f"Hello, {name}!"
result = greet("Aman")
print(result) # Hello, Aman!
3.2 Function with No Return (void)
def print_line():
print("-" * 30)
print_line() # just prints, returns None
3.3 Positional and Keyword Arguments
def add(a, b):
return a + b
add(3, 5) # positional — order matters
add(b=5, a=3) # keyword — order doesn't matter
add(3, b=5) # mixed — positional first
3.4 Default Arguments
def greet(name, msg="Hello"):
print(f"{msg}, {name}!")
greet("Aman") # Hello, Aman!
greet("Aman", "Hi") # Hi, Aman!
greet("Aman", msg="Hey") # Hey, Aman!
■ Default args MUST come after non-default args: def f(a, b=5) OK. def f(a=5, b) ERROR.
3.5 *args — Variable Positional Arguments
Python for Data Analysis — Master Source Page 12
def total(*args):
return sum(args) # args is a TUPLE
print(total(1,2)) # 3
print(total(1,2,3,4,5)) # 15
def show(*args):
for item in args:
print(item)
show("a","b","c")
3.6 **kwargs — Variable Keyword Arguments
def info(**kwargs):
for key, val in [Link]():
print(f"{key}: {val}")
info(name="Aman", age=20, city="Gurugram")
# name: Aman
# age: 20
# city: Gurugram
# kwargs is a DICT inside the function
3.7 Mixing All Argument Types
def example(a, b, *args, **kwargs):
print(a, b) # positional
print(args) # tuple of extra positional
print(kwargs) # dict of extra keyword
example(1, 2, 3, 4, x=10, y=20)
# 1 2
# (3, 4)
# {'x': 10, 'y': 20}
3.8 Scope — LEGB Rule
Python for Data Analysis — Master Source Page 13
# L = Local, E = Enclosing, G = Global, B = Built-in
x = 10 # Global
def outer():
y = 20 # Enclosing
def inner():
z = 30 # Local
print(x, y, z) # can see all three
inner()
# global keyword
counter = 0
def increment():
global counter
counter += 1 # modify global variable
# nonlocal keyword
def outer():
count = 0
def inner():
nonlocal count
count += 1 # modify enclosing variable
inner()
print(count) # 1
PRACTICE QUESTIONS — Functions
Q1. Write a function to check if a number is even or odd.
→ Return True if even.
def is_even(n):
return n % 2 == 0
print(is_even(4)) # True
print(is_even(7)) # False
Q2. Write a function that returns the factorial of n.
→ Use a loop inside function.
def factorial(n):
result = 1
for i in range(1, n+1):
result *= i
return result
print(factorial(5)) # 120
Q3. Write a function that takes *args and returns their average.
→ sum(args)/len(args).
def average(*args):
return sum(args) / len(args)
print(average(10, 20, 30)) # 20.0
Python for Data Analysis — Master Source Page 14
Q4. Write a function that prints **kwargs as a user profile.
→ Iterate [Link]().
def profile(**kwargs):
for k, v in [Link]():
print(f"{k}: {v}")
profile(name="Aman", age=20, course="BBA")
Q5. Write a function to convert Celsius to Fahrenheit with default parameter.
→ Default scale='F'.
def convert(temp, scale="F"):
if scale == "F":
return temp * 9/5 + 32
return (temp - 32) * 5/9
print(convert(100)) # 212.0
print(convert(212, "C")) # 100.0
Q6. Write a function that returns BOTH min and max of a list.
→ Return tuple.
def min_max(lst):
return min(lst), max(lst)
lo, hi = min_max([3,1,7,4,9])
print(lo, hi) # 1 9
Q7. Write a function to count occurrences of a value in a list.
→ Use .count().
def count_val(lst, val):
return [Link](val)
print(count_val([1,2,2,3,2], 2)) # 3
Q8. Write a function using global keyword to track call count.
→ global counter.
call_count = 0
def my_func():
global call_count
call_count += 1
print(f"Called {call_count} times")
my_func(); my_func(); my_func()
Q9. Write a function to flatten a 2D list.
→ Nested loop.
def flatten(matrix):
result = []
for row in matrix:
for val in row:
[Link](val)
return result
print(flatten([[1,2],[3,4],[5,6]])) # [1,2,3,4,5,6]
Python for Data Analysis — Master Source Page 15
Q10. Write a function with docstring and demonstrate help().
→ """docstring""".
def area(r):
"""Calculate area of a circle given radius r."""
import math
return [Link] * r ** 2
help(area)
print(area(5))
Python for Data Analysis — Master Source Page 16
Chapter 4: Lambda & lambda, map(), filter(), reduce()
Functional Tools
Lambda is an anonymous (nameless) one-line function. map/filter/reduce are functional tools that apply
functions over iterables elegantly.
4.1 Lambda Function
lambda parameters: expression
# Named lambda (unusual but valid)
square = lambda x: x**2
print(square(5)) # 25
add = lambda a,b: a+b
print(add(3,4)) # 7
# Most common use: inside sorted/map/filter
nums = [3,1,4,1,5,9]
[Link](key=lambda x: -x) # sort descending
4.2 map() — Apply Function to All Elements
map(function, iterable) → iterator
nums = [1,2,3,4,5]
squared = list(map(lambda x: x**2, nums))
print(squared) # [1,4,9,16,25]
# With def function
def double(x): return x*2
result = list(map(double, nums))
4.3 filter() — Keep Elements Where Condition is True
filter(function, iterable) → iterator
nums = [1,2,3,4,5,6,7,8]
evens = list(filter(lambda x: x%2==0, nums))
print(evens) # [2,4,6,8]
words = ["hi","hello","hey","bye"]
h_words = list(filter(lambda w: [Link]("h"), words))
print(h_words) # ['hi', 'hello', 'hey']
4.4 reduce() — Accumulate to Single Value
Python for Data Analysis — Master Source Page 17
from functools import reduce
nums = [1,2,3,4,5]
product = reduce(lambda a,b: a*b, nums)
print(product) # 120 (1*2*3*4*5)
total = reduce(lambda a,b: a+b, nums)
print(total) # 15
PRACTICE QUESTIONS — Lambda & Functional Tools
Q1. Use lambda to cube a number.
→ lambda x: x**3
cube = lambda x: x**3
print(cube(3)) # 27
Q2. Use map() to convert a list of Celsius values to Fahrenheit.
→ Apply formula with map+lambda.
celsius = [0, 20, 37, 100]
fahrenheit = list(map(lambda c: c*9/5+32, celsius))
print(fahrenheit)
Q3. Use filter() to get words longer than 4 characters.
→ lambda w: len(w)>4
words = ["hi","hello","Python","AI","data"]
long = list(filter(lambda w: len(w)>4, words))
print(long) # ['hello', 'Python']
Q4. Use reduce() to find the maximum of a list.
→ lambda a,b: a if a>b else b
from functools import reduce
nums = [3,9,1,7,4]
mx = reduce(lambda a,b: a if a>b else b, nums)
print(mx) # 9
Q5. Sort a list of tuples by the second element using lambda.
→ key=lambda t: t[1]
data = [("Alice",25),("Bob",20),("Charlie",30)]
[Link](key=lambda t: t[1])
print(data)
Q6. Use map() to extract just the names from a list of dicts.
→ map(lambda d: d['name'], ...)
people = [{"name":"Aman","age":20},{"name":"Riya","age":22}]
names = list(map(lambda d: d["name"], people))
print(names) # ['Aman', 'Riya']
Q7. Chain map and filter: square only even numbers from 1-10.
→ filter first, then map.
nums = range(1,11)
result = list(map(lambda x: x**2, filter(lambda x: x%2==0, nums)))
print(result) # [4,16,36,64,100]
Python for Data Analysis — Master Source Page 18
base case, recursive case,
Chapter 5: Recursion factorial, fibonacci, patterns
Recursion is when a function CALLS ITSELF. Every recursive solution needs: (1) Base case — when to
STOP, (2) Recursive case — calling itself with smaller input.
5.1 Structure of Recursion
def recursive_function(n):
if n == base_case: # STOP condition
return base_value
return recursive_function(smaller_n)
5.2 Factorial
def factorial(n):
if n == 0 or n == 1: # base case
return 1
return n * factorial(n-1)
factorial(5) = 5 * factorial(4)
= 5 * 4 * factorial(3)
= 5 * 4 * 3 * 2 * 1 = 120
5.3 Fibonacci
def fib(n):
if n <= 1:
return n
return fib(n-1) + fib(n-2)
# fib(0)=0, fib(1)=1, fib(5)=5
5.4 Sum of List Recursively
def list_sum(lst):
if not lst: # empty list = base case
return 0
return lst[0] + list_sum(lst[1:])
print(list_sum([1,2,3,4,5])) # 15
PRACTICE QUESTIONS — Recursion
Q1. Write recursive function to find power(base, exp).
→ base * power(base,exp-1)
def power(base, exp):
if exp == 0: return 1
return base * power(base, exp-1)
print(power(2,8)) # 256
Python for Data Analysis — Master Source Page 19
Q2. Write recursive function to reverse a string.
→ s[-1] + reverse(s[:-1])
def reverse(s):
if len(s) <= 1: return s
return s[-1] + reverse(s[:-1])
print(reverse("Python")) # nohtyP
Q3. Count occurrences of element in list recursively.
→ Check head, recur on tail.
def count(lst, val):
if not lst: return 0
return (1 if lst[0]==val else 0) + count(lst[1:], val)
print(count([1,2,2,3,2],2)) # 3
Python for Data Analysis — Master Source Page 20
Chapter 6: Data list, tuple, set, dict, string — all
Structures ops
Python's built-in data structures are the containers that hold your data. Knowing WHICH one to use and all
their operations is essential for data analysis.
6.1 Lists — Ordered, Mutable
lst = [1,2,3,4,5]
lst[0] # access: 1
lst[-1] # last: 5
lst[1:3] # slice: [2,3]
[Link](6) # add end
[Link](0,0) # add at index
[Link]([7,8]) # merge list
[Link](3) # remove by value
[Link]() # remove last
[Link](2) # remove at index
del lst[0] # delete by index
[Link]() # sort in place
[Link]() # reverse in place
sorted(lst) # returns new sorted list
[Link](4) # find index of value
[Link](2) # count occurrences
len(lst) # length
2 in lst # membership
# List comprehension
squares = [x**2 for x in range(10)]
evens = [x for x in range(20) if x%2==0]
6.2 Tuples — Ordered, Immutable
t = (1,2,3)
t[0] # access
t[1:] # slicing
len(t) # length
[Link](2) # count
[Link](3) # find index
# Packing and unpacking
a, b, c = t # unpack
a, *rest = t # extended unpack
# Single-element tuple NEEDS comma
x = (5,) # tuple. x=(5) is just int
# Tuple as dict key (immutable = hashable)
d = {(0,0): "origin", (1,0): "right"}
6.3 Sets — Unordered, Unique Elements
Python for Data Analysis — Master Source Page 21
s = {1,2,3,4}
[Link](5) # add element
[Link](3) # remove (error if missing)
[Link](10) # remove safely
len(s) # size
# Set operations
a = {1,2,3,4}
b = {3,4,5,6}
a | b # union {1,2,3,4,5,6}
a & b # intersection {3,4}
a - b # difference {1,2}
a ^ b # symmetric diff {1,2,5,6}
# Remove duplicates from list
clean = list(set([1,2,2,3,3,3]))
6.4 Dictionaries — Key-Value Pairs
d = {"name":"Aman","age":20,"city":"Gurugram"}
d["name"] # access value
[Link]("phone","N/A")# safe access with default
d["email"] = "a@[Link]" # add/update
del d["city"] # delete key
[Link]() # all keys
[Link]() # all values
[Link]() # key-value tuples
"name" in d # membership check
[Link]({"age":21})# merge/update
[Link]("age") # remove and return
# Dict comprehension
sq = {x: x**2 for x in range(1,6)}
# {1:1, 2:4, 3:9, 4:16, 5:25}
# Nested dict
student = {"name":"Aman","marks":{"math":90,"sci":85}}
student["marks"]["math"] # 90
6.5 Strings — Immutable Sequences
Python for Data Analysis — Master Source Page 22
s = "Hello, Python!"
s[0] # H
s[-1] # !
s[0:5] # Hello
[Link]() # HELLO, PYTHON!
[Link]() # hello, python!
[Link]() # remove whitespace
[Link](); [Link]()
[Link](",") # ['Hello', ' Python!']
" ".join(["a","b"]) # a b
[Link]("Python","World")
[Link]("Python") # index or -1
[Link]("l") # count occurrences
[Link]("He") # True
[Link]("!") # True
[Link]() # all digits?
[Link]() # all letters?
[Link]() # all alphanumeric?
len(s) # length
# f-string (most modern)
name = "Aman"; age = 20
f"{name} is {age} years old"
# format()
"{} is {} years old".format(name, age)
PRACTICE QUESTIONS — Data Structures
Q1. Remove duplicates from a list preserving order.
→ Convert to set then back — loses order. Use loop.
def remove_dups(lst):
seen = set()
result = []
for x in lst:
if x not in seen:
[Link](x)
[Link](x)
return result
print(remove_dups([1,2,2,3,1,4])) # [1,2,3,4]
Q2. Count word frequency in a sentence using dict.
→ Split and count.
sentence = "the cat sat on the mat the cat"
freq = {}
for word in [Link]():
freq[word] = [Link](word, 0) + 1
print(freq)
Q3. Find common elements in two lists.
→ Use set intersection.
a = [1,2,3,4,5]
b = [3,4,5,6,7]
print(list(set(a) & set(b))) # [3,4,5]
Python for Data Analysis — Master Source Page 23
Q4. Reverse words in a sentence.
→ split, reverse, join.
s = "I love Python"
print(" ".join([Link]()[::-1])) # Python love I
Q5. Flatten a nested list.
→ Nested loop.
nested = [[1,2],[3,4],[5,6]]
flat = [x for row in nested for x in row]
print(flat) # [1,2,3,4,5,6]
Q6. Check if two strings are anagrams.
→ Sort both and compare.
def is_anagram(a, b):
return sorted([Link]()) == sorted([Link]())
print(is_anagram("listen","silent")) # True
Q7. Merge two dicts (Python 3.9+).
→ Use | operator or update().
d1 = {"a":1,"b":2}
d2 = {"c":3,"d":4}
merged = d1 | d2
print(merged)
Q8. Find the most common element in a list.
→ Use Counter.
from collections import Counter
lst = [1,2,2,3,2,4,3]
c = Counter(lst)
print(c.most_common(1)) # [(2, 3)]
Python for Data Analysis — Master Source Page 24
try/except/else/finally, raise,
Chapter 7: Error & custom exceptions, all error
Exception Handling types
Errors (exceptions) are Python's way of telling you something went wrong at runtime. Exception handling lets
your program RESPOND to errors gracefully instead of crashing. This is critical in data analysis — files may
be missing, data may be bad, network may fail.
7.1 Types of Python Errors
SyntaxError — wrong Python syntax (before running)
IndentationError — wrong indentation
NameError — variable not defined
TypeError — wrong type operation
ValueError — right type, wrong value
IndexError — list index out of range
KeyError — dict key not found
AttributeError — object has no attribute
ZeroDivisionError— divide by zero
FileNotFoundError— file doesn't exist
ImportError — module not found
RuntimeError — general runtime error
StopIteration — iterator exhausted
MemoryError — not enough RAM
OverflowError — number too large
RecursionError — max recursion exceeded
7.2 Basic try-except
try:
risky_code()
except ExceptionType:
handle_error()
# Example
try:
n = int(input("Enter number: "))
print(10 / n)
except ValueError:
print("That's not a number!")
except ZeroDivisionError:
print("Cannot divide by zero!")
7.3 Catching Multiple Exceptions
Python for Data Analysis — Master Source Page 25
# Method 1: Multiple except blocks
try:
x = int(input())
result = 10 / x
lst = [1,2,3]
print(lst[x])
except ValueError:
print("Invalid number")
except ZeroDivisionError:
print("Division by zero")
except IndexError:
print("Index out of range")
# Method 2: Tuple of exceptions
except (ValueError, TypeError):
print("Value or Type error")
# Catch ALL exceptions (use sparingly)
except Exception as e:
print(f"Error: {e}")
7.4 else and finally
try:
result = 10 / 2
except ZeroDivisionError:
print("Error!")
else:
print("Success:", result) # runs if NO exception
finally:
print("Always runs") # runs NO MATTER WHAT
# finally is for cleanup: close files, DB connections
try:
f = open("[Link]")
data = [Link]()
except FileNotFoundError:
print("File not found")
finally:
[Link]() # always close the file
7.5 Getting Exception Details (as e)
try:
x = 1 / 0
except ZeroDivisionError as e:
print(type(e).__name__) # ZeroDivisionError
print(str(e)) # division by zero
print(repr(e)) # full representation
7.6 raise — Manually Raise an Exception
Python for Data Analysis — Master Source Page 26
# Raise when condition is invalid
def set_age(age):
if age < 0:
raise ValueError("Age cannot be negative")
return age
try:
set_age(-5)
except ValueError as e:
print(e) # Age cannot be negative
# Re-raise inside except
try:
x = int("abc")
except ValueError:
print("Caught it")
raise # re-raises same exception
7.7 Custom (User-Defined) Exceptions
# Create by inheriting from Exception
class InsufficientFundsError(Exception):
def __init__(self, amount, balance):
[Link] = amount
[Link] = balance
super().__init__(
f"Cannot withdraw {amount}. Balance: {balance}"
)
class BankAccount:
def __init__(self, balance):
[Link] = balance
def withdraw(self, amount):
if amount > [Link]:
raise InsufficientFundsError(amount, [Link])
[Link] -= amount
return [Link]
account = BankAccount(1000)
try:
[Link](1500)
except InsufficientFundsError as e:
print(e)
7.8 Exception Hierarchy
Python for Data Analysis — Master Source Page 27
BaseException
■■■ SystemExit
■■■ KeyboardInterrupt
■■■ Exception
■■■ ArithmeticError
■ ■■■ ZeroDivisionError
■ ■■■ OverflowError
■■■ LookupError
■ ■■■ IndexError
■ ■■■ KeyError
■■■ ValueError
■■■ TypeError
■■■ AttributeError
■■■ NameError
■■■ FileNotFoundError (OSError)
■■■ RuntimeError
■ ALWAYS catch specific exceptions before generic ones. Put 'except Exception' at the end if needed.
7.9 Context Manager (with statement) for Safe File Ops
# Automatically closes file even if exception occurs
with open("[Link]", "r") as f:
data = [Link]()
# No need for finally + [Link]()
# Custom context manager
class ManagedResource:
def __enter__(self):
print("Acquiring resource")
return self
def __exit__(self, exc_type, exc_val, exc_tb):
print("Releasing resource")
return False # don't suppress exceptions
PRACTICE QUESTIONS — Error & Exception Handling
Q1. Handle ZeroDivisionError when user enters 0.
→ Wrap division in try-except.
try:
n = int(input("Enter divisor: "))
print(100 / n)
except ZeroDivisionError:
print("Cannot divide by zero!")
except ValueError:
print("Please enter a valid number")
Q2. Open a file and handle FileNotFoundError.
→ try-except-finally.
try:
with open("[Link]") as f:
print([Link]())
except FileNotFoundError:
print("File not found!")
finally:
print("Attempted file operation")
Python for Data Analysis — Master Source Page 28
Q3. Validate age input: raise ValueError if age < 0 or > 150.
→ raise inside function.
def validate_age(age):
if age < 0 or age > 150:
raise ValueError(f"Invalid age: {age}")
return age
try:
validate_age(-5)
except ValueError as e:
print(e)
Q4. Create custom exception 'InvalidGradeError' for grades outside 0-100.
→ Inherit from Exception.
class InvalidGradeError(Exception):
pass
def set_grade(g):
if not (0 <= g <= 100):
raise InvalidGradeError(f"Grade {g} is invalid")
return g
try:
set_grade(105)
except InvalidGradeError as e:
print(e)
Q5. Catch both KeyError and IndexError in one except.
→ Tuple of exceptions.
try:
d = {"a":1}
print(d["z"])
except (KeyError, IndexError) as e:
print(f"Lookup error: {e}")
Q6. Use else to confirm successful execution.
→ else runs when no exception.
try:
result = int("123")
except ValueError:
print("Conversion failed")
else:
print("Converted successfully:", result)
Q7. Handle TypeError when adding int and string.
→ Catch TypeError.
try:
result = "Hello" + 5
except TypeError as e:
print("Type error:", e)
Q8. Use finally to always print 'Program ended'.
→ finally block.
try:
x = 10 / 0
except ZeroDivisionError:
print("Error caught")
finally:
print("Program ended")
Python for Data Analysis — Master Source Page 29
Q9. Write a safe integer input function (keeps asking until valid).
→ Loop with try-except ValueError.
def get_int(prompt):
while True:
try:
return int(input(prompt))
except ValueError:
print("Invalid! Enter a whole number.")
n = get_int("Enter a number: ")
print("You entered:", n)
Q10. Demonstrate all: try, except, else, finally together.
→ Complete structure.
def safe_divide(a, b):
try:
result = a / b
except ZeroDivisionError:
print("Cannot divide by zero")
except TypeError:
print("Both must be numbers")
else:
print("Result:", result)
return result
finally:
print("safe_divide() called")
safe_divide(10, 2)
safe_divide(10, 0)
Q11. Create a custom exception hierarchy: AppError > DataError > MissingFieldError.
→ Chain inheritance.
class AppError(Exception): pass
class DataError(AppError): pass
class MissingFieldError(DataError):
def __init__(self, field):
super().__init__(f"Missing required field: {field}")
try:
raise MissingFieldError("email")
except AppError as e:
print(e) # caught by parent
Q12. Handle AttributeError when accessing method on None.
→ Check for None first.
data = None
try:
print([Link]())
except AttributeError:
print("data is None or has no .upper() method")
Python for Data Analysis — Master Source Page 30
Q13. Use assert to check preconditions.
→ assert with custom message.
def square_root(n):
assert n >= 0, f"Cannot take sqrt of negative: {n}"
return n ** 0.5
try:
print(square_root(-4))
except AssertionError as e:
print("AssertionError:", e)
Q14. Write a retry mechanism: try operation up to 3 times.
→ Loop + try-except.
import random
def risky():
if [Link]() < 0.7:
raise RuntimeError("Random failure!")
return "Success"
for attempt in range(1,4):
try:
result = risky()
print(result)
break
except RuntimeError as e:
print(f"Attempt {attempt} failed: {e}")
else:
print("All attempts failed")
Python for Data Analysis — Master Source Page 31
arrays, indexing, operations,
Chapter 8: NumPy broadcasting, random
NumPy (Numerical Python) is the foundation of ALL data science in Python. It provides N-dimensional arrays
and fast mathematical operations. Pandas, Matplotlib, and sklearn all build on NumPy.
8.1 Creating Arrays
import numpy as np
[Link]([1,2,3]) # 1D from list
[Link]([[1,2],[3,4]]) # 2D (matrix)
[Link]((3,4)) # 3x4 zeros
[Link]((2,3)) # 2x3 ones
[Link]((2,2), 7) # filled with 7
[Link](3) # 3x3 identity
[Link](0,10,2) # [0,2,4,6,8]
[Link](0,1,5) # 5 evenly spaced 0-1
[Link](3,3) # uniform random 0-1
[Link](3,3) # normal distribution
[Link](0,10,(3,3)) # random ints
8.2 Array Properties
a = [Link]([[1,2,3],[4,5,6]])
[Link] # (2,3) — rows,cols
[Link] # 2 — dimensions
[Link] # 6 — total elements
[Link] # int64 — data type
[Link](3,2) # reshape (same elements)
[Link]() # to 1D
a.T # transpose
8.3 Indexing and Slicing
a = [Link]([10,20,30,40,50])
a[0]; a[-1] # 10, 50
a[1:4] # [20,30,40]
a[::2] # [10,30,50]
m = [Link]([[1,2,3],[4,5,6],[7,8,9]])
m[0,:] # first row [1,2,3]
m[:,1] # second col [2,5,8]
m[0:2,1:3] # sub-matrix [[2,3],[5,6]]
# Boolean indexing
a = [Link]([1,2,3,4,5])
a[a > 3] # [4,5]
a[a%2==0] # [2,4]
8.4 Operations
Python for Data Analysis — Master Source Page 32
a = [Link]([1,2,3])
b = [Link]([4,5,6])
a + b; a - b; a * b; a / b # element-wise
a ** 2 # [1,4,9]
[Link](a,b) # dot product: 32
a @ b # same
[Link](a); [Link](a); [Link](a)
[Link](a); [Link](a)
[Link](a) # cumulative sum
[Link](a)
# Axis operations (on 2D)
m = [Link]([[1,2],[3,4]])
[Link](m, axis=0) # col sums [4,6]
[Link](m, axis=1) # row sums [3,7]
PRACTICE QUESTIONS — NumPy
Q1. Create a 5x5 matrix of zeros, then set diagonal to 1 without eye().
→ Use [Link] then set [i,i]=1.
import numpy as np
m = [Link]((5,5))
for i in range(5):
m[i,i] = 1
print(m)
Q2. Find mean, median, and std of an array.
→ [Link], [Link], [Link].
a = [Link]([10,20,30,40,50])
print("Mean:", [Link](a))
print("Median:", [Link](a))
print("Std:", [Link](a))
Q3. Normalize an array to 0-1 range.
→ (x-min)/(max-min)
a = [Link]([10.0,20,30,40,50])
normalized = (a - [Link]()) / ([Link]() - [Link]())
print(normalized)
Q4. Extract all elements greater than mean.
→ Boolean indexing.
a = [Link]([1,5,3,9,2,7,4])
print(a[a > [Link]()])
Q5. Stack two arrays vertically and horizontally.
→ [Link], [Link].
a = [Link]([[1,2],[3,4]])
b = [Link]([[5,6],[7,8]])
print([Link]([a,b]))
print([Link]([a,b]))
Python for Data Analysis — Master Source Page 33
Series, DataFrame, loc/iloc,
Chapter 9: Pandas filter, sort, groupby, merge
Pandas is THE data manipulation library for Python. It provides DataFrame (like an Excel sheet) and Series
(like a column). 90% of real data analysis work is done in Pandas.
9.1 Series
import pandas as pd
s = [Link]([10,20,30,40], index=["a","b","c","d"])
s["a"] # 10
s[["a","c"]] # multiple
s[s > 20] # boolean filter
[Link] # numpy array
[Link] # index
[Link](); [Link](); [Link](); [Link]()
s.value_counts()
9.2 DataFrame Basics
df = pd.read_csv("[Link]")
df = [Link]({
"name":["Aman","Riya","Sam"],
"age":[20,22,21],
"marks":[85,90,78]
})
[Link](3) # first 3 rows
[Link](3) # last 3 rows
[Link] # (rows, cols)
[Link]() # dtypes, nulls
[Link]() # statistics
[Link] # column types
[Link] # column names
df["marks"] # select column (Series)
df[["name","marks"]] # select multiple cols
df["grade"] = "A" # add column
del df["grade"] # delete column
[Link](columns={"marks":"score"}, inplace=True)
9.3 loc and iloc
# loc — label based
[Link][0] # row at index label 0
[Link][0, "name"] # specific cell
[Link][0:2, "name":"age"] # slice
[Link][df["age"]>20] # conditional
# iloc — integer position based
[Link][0] # first row
[Link][0,1] # row 0, col 1
[Link][0:3, 0:2] # slice
Python for Data Analysis — Master Source Page 34
9.4 Filtering and Sorting
df[df["age"] > 20] # single condition
df[(df["age"]>20) & (df["marks"]>80)] # AND
df[(df["age"]>20) | (df["marks"]>80)] # OR
df[df["name"].isin(["Aman","Riya"])] # isin
[Link]("age > 20 and marks > 80") # query string
df.sort_values("marks") # ascending
df.sort_values("marks", ascending=False)
df.sort_values(["age","marks"]) # multi-col
[Link](3,"marks") # top 3
9.5 GroupBy
[Link]("dept")["salary"].mean()
[Link]("dept").agg({"salary":["mean","max"],"age":"count"})
[Link]("dept").apply(lambda g: [Link](1,"salary"))
[Link]("city")["marks"].transform("mean") # fill back
9.6 Merge and Concat
# Merge (like SQL join)
merged = [Link](df1, df2, on="id", how="inner")
# how: inner/left/right/outer
# Concat (stack rows or cols)
combined = [Link]([df1,df2], ignore_index=True) # rows
side_by = [Link]([df1,df2], axis=1) # cols
PRACTICE QUESTIONS — Pandas
Q1. Load a CSV and display basic info.
→ read_csv, head, info, describe.
import pandas as pd
df = pd.read_csv("[Link]")
print([Link]())
print([Link]())
print([Link]())
Q2. Select rows where marks > 80 AND age < 22.
→ Boolean indexing with &.
result = df[(df['marks']>80) & (df['age']<22)]
print(result)
Q3. Add a 'grade' column: A if marks>=90, B if >=80, else C.
→ [Link] or apply.
import numpy as np
conditions = [df["marks"]>=90, df["marks"]>=80]
choices = ["A","B"]
df["grade"] = [Link](conditions, choices, default="C")
Q4. Find average marks by department using groupby.
→ groupby + mean.
print([Link]('dept')['marks'].mean())
Python for Data Analysis — Master Source Page 35
Q5. Pivot table: average salary by dept and gender.
→ pivot_table.
pt = df.pivot_table(values="salary", index="dept",
columns="gender", aggfunc="mean")
print(pt)
Q6. Left join two DataFrames on 'student_id'.
→ [Link] with how='left'.
merged = [Link](df_students, df_grades,
on="student_id", how="left")
Python for Data Analysis — Master Source Page 36
missing values, duplicates,
Chapter 10: Data Cleaning outliers, type conversion
Real-world data is MESSY. Data cleaning is 60-70% of any data analysis project. You'll deal with missing
values, wrong types, duplicates, and outliers constantly.
10.1 Missing Values
[Link]() # boolean mask
[Link]().sum() # count per column
[Link]().sum().sum() # total missing
[Link]()
# Handle missing
[Link]() # drop rows with ANY null
[Link](axis=1) # drop cols with ANY null
[Link](thresh=3) # keep rows with >=3 non-null
df["col"].fillna(0) # fill with constant
df["col"].fillna(df["col"].mean()) # fill with mean
df["col"].fillna(method="ffill") # forward fill
df["col"].fillna(method="bfill") # backward fill
df["col"].interpolate() # linear interpolation
10.2 Duplicates
[Link]() # boolean mask
[Link]().sum() # count duplicates
df.drop_duplicates() # remove all
df.drop_duplicates(subset=["name"]) # based on col
df.drop_duplicates(keep="last") # keep last occurrence
10.3 Outliers
# IQR Method
Q1 = df["col"].quantile(0.25)
Q3 = df["col"].quantile(0.75)
IQR = Q3 - Q1
lower = Q1 - 1.5*IQR
upper = Q3 + 1.5*IQR
df_clean = df[(df["col"]>=lower) & (df["col"]<=upper)]
# Z-score Method
from scipy import stats
z = [Link](df["col"])
df_clean = df[abs(z) < 3]
# Capping (Winsorization)
df["col"] = df["col"].clip(lower, upper)
10.4 Type Conversion
Python for Data Analysis — Master Source Page 37
df["age"] = df["age"].astype(int)
df["price"] = df["price"].astype(float)
df["date"] = pd.to_datetime(df["date"])
df["value"] = pd.to_numeric(df["value"], errors="coerce")
df["cat"] = df["cat"].astype("category")
PRACTICE QUESTIONS — Data Cleaning
Q1. Find columns with missing values and their percentage.
→ isnull().sum() / len(df) * 100
missing_pct = [Link]().sum() / len(df) * 100
print(missing_pct[missing_pct>0])
Q2. Fill missing age with median, missing name with 'Unknown'.
→ fillna separately per column.
df["age"].fillna(df["age"].median(), inplace=True)
df["name"].fillna("Unknown", inplace=True)
Q3. Remove outliers from 'salary' column using IQR.
→ Compute bounds, filter.
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)]
Python for Data Analysis — Master Source Page 38
Chapter 11: Data groupby, pivot, melt, apply,
Manipulation concat, merge
11.1 apply / map / transform
df["marks_sq"] = df["marks"].apply(lambda x: x**2)
df["marks_sq"] = df["marks"].map(lambda x: x**2)
df["dept_avg"] = [Link]("dept")["marks"].transform("mean")
df[["a","b"]] = df[["a","b"]].apply([Link])
11.2 Pivot and Melt
# pivot_table
pt = df.pivot_table(values="sales",index="region",
columns="product",aggfunc="sum",fill_value=0)
# melt — wide to long
melted = [Link](df, id_vars=["name"],
value_vars=["q1","q2","q3"],
var_name="quarter", value_name="sales")
PRACTICE QUESTIONS — Manipulation
Q1. Find top 2 earners per department.
→ groupby + apply nlargest.
[Link]('dept').apply(lambda g: [Link](2,'salary')).reset_index(drop=True)
Q2. Create running total of sales per region.
→ groupby + cumsum.
df['running_total'] = [Link]('region')['sales'].cumsum()
Q3. Melt a wide DataFrame (Q1,Q2,Q3,Q4 cols) to long format.
→ [Link].
melted = [Link](df, id_vars=['product'],
value_vars=['Q1','Q2','Q3','Q4'],
var_name='Quarter', value_name='Sales')
Python for Data Analysis — Master Source Page 39
Chapter 12: EDA — describe, corr, value_counts,
Exploratory Data Analysis distribution
12.1 Descriptive Statistics
[Link]() # all numeric stats
df["col"].value_counts() # frequency table
df["col"].value_counts(normalize=True) # proportions
[Link]() # correlation matrix
df["col"].skew() # skewness
df["col"].kurt() # kurtosis
[Link](df["dept"],df["gender"])
PRACTICE QUESTIONS — EDA
Q1. Find top 5 most common values in a column.
→ value_counts().head(5).
print(df['city'].value_counts().head(5))
Q2. Find correlation between all numeric columns.
→ [Link]() + heatmap.
import seaborn as sns
import [Link] as plt
[Link]([Link](), annot=True, cmap="coolwarm")
[Link]()
Python for Data Analysis — Master Source Page 40
Matplotlib & Seaborn — all chart
Chapter 13: Visualization types
13.1 Matplotlib — Core Charts
import [Link] as plt
# Line plot
[Link](x, y, color="blue", linestyle="--", marker="o")
# Bar chart
[Link](categories, values, color="steelblue")
[Link](categories, values) # horizontal
# Histogram
[Link](data, bins=20, color="green", edgecolor="black")
# Scatter plot
[Link](x, y, color="red", alpha=0.5, s=50)
# Pie chart
[Link](values, labels=labels, autopct="%1.1f%%")
# Subplots
fig, axes = [Link](2,2, figsize=(10,8))
axes[0,0].plot(x,y)
# Labels
[Link]("My Chart")
[Link]("X Axis"); [Link]("Y Axis")
[Link](); [Link](True)
plt.tight_layout(); [Link]()
13.2 Seaborn — Statistical Charts
import seaborn as sns
[Link]([Link](), annot=True, cmap="coolwarm")
[Link](x="dept", y="salary", data=df)
[Link](x="dept", y="salary", data=df)
[Link](df["age"], kde=True, bins=20)
[Link](x="age", y="salary", hue="dept", data=df)
[Link](df, hue="dept")
[Link](x="dept", y="salary", data=df)
[Link](x="month", y="sales", data=df)
[Link](x="dept",y="salary",kind="box",data=df)
[Link](x="age",y="salary",data=df)
PRACTICE QUESTIONS — Visualization
Python for Data Analysis — Master Source Page 41
Q1. Plot salary distribution as histogram with KDE.
→ [Link] with kde=True.
import seaborn as sns, [Link] as plt
[Link](df["salary"], kde=True, bins=30)
[Link]("Salary Distribution")
[Link]()
Q2. Create 2x2 subplot: line, bar, scatter, histogram.
→ fig, axes = [Link](2,2).
fig, axes = [Link](2,2,figsize=(12,8))
axes[0,0].plot(x,y); axes[0,0].set_title("Line")
axes[0,1].bar(cat,val); axes[0,1].set_title("Bar")
axes[1,0].scatter(x,y); axes[1,0].set_title("Scatter")
axes[1,1].hist(data,bins=20); axes[1,1].set_title("Hist")
plt.tight_layout(); [Link]()
Python for Data Analysis — Master Source Page 42
Chapter 14: Statistics for mean/std, distributions,
Data Analysis hypothesis testing
14.1 Descriptive Statistics
import numpy as np
from scipy import stats
data = [23,25,28,22,29,24,27,26]
[Link](data) # arithmetic mean
[Link](data) # middle value
[Link](data) # most frequent
[Link](data) # standard deviation
[Link](data) # variance
[Link](data,75) # 75th percentile
14.2 Hypothesis Testing
from scipy import stats
# t-test: compare means of two groups
t_stat, p_value = stats.ttest_ind(group1, group2)
if p_value < 0.05:
print("Significant difference")
# chi-square: categorical independence
chi2, p, dof, expected = stats.chi2_contingency(contingency_table)
# One-sample t-test
t, p = stats.ttest_1samp(data, popmean=50)
PRACTICE QUESTIONS — Statistics
Q1. Test if males and females have significantly different salaries.
→ ttest_ind, check p<0.05.
from scipy import stats
males = df[df["gender"]=="M"]["salary"]
females = df[df["gender"]=="F"]["salary"]
t, p = stats.ttest_ind(males, females)
print("p-value:", p)
print("Significant" if p < 0.05 else "Not significant")
Python for Data Analysis — Master Source Page 43
Chapter 15: Intro to
regression, classification,
sklearn / Machine evaluation
Learning
15.1 ML Workflow
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LinearRegression, LogisticRegression
from [Link] import accuracy_score, mean_squared_error, confusion_matrix
from [Link] import StandardScaler
# 1. Split data
X_train,X_test,y_train,y_test = train_test_split(X, y, test_size=0.2, random_state=42)
# 2. Scale features
scaler = StandardScaler()
X_train = scaler.fit_transform(X_train)
X_test = [Link](X_test)
# 3. Train model
model = LinearRegression()
[Link](X_train, y_train)
# 4. Predict
y_pred = [Link](X_test)
# 5. Evaluate
print("MSE:", mean_squared_error(y_test, y_pred))
print("Accuracy:", accuracy_score(y_test, y_pred)) # classification
print(confusion_matrix(y_test, y_pred))
PRACTICE QUESTIONS — sklearn
Q1. Build a linear regression model to predict salary from years of experience.
→ X=experience, y=salary, fit LinearRegression.
from sklearn.linear_model import LinearRegression
from sklearn.model_selection import train_test_split
import numpy as np
X = df[["experience"]]
y = df["salary"]
X_tr,X_te,y_tr,y_te = train_test_split(X,y,test_size=0.2,random_state=42)
model = LinearRegression()
[Link](X_tr, y_tr)
print("Score:", [Link](X_te, y_te))
Q2. Evaluate a classification model with confusion matrix and accuracy.
→ accuracy_score + confusion_matrix.
from [Link] import accuracy_score, confusion_matrix, classification_report
print("Accuracy:", accuracy_score(y_test, y_pred))
print(confusion_matrix(y_test, y_pred))
print(classification_report(y_test, y_pred))
Python for Data Analysis — Master Source Page 44
YOU NOW HAVE THE MASTER
SOURCE
15 Chapters • 50+ Concepts • 200+ Logic Patterns • 150+ Practice Q&A;
Control Flow | Loops | Functions | Lambda | Recursion | Data Structures
Error Handling | NumPy | Pandas | Cleaning | EDA | Viz | Stats | sklearn
Prepared for Aman — MDU BBA | Python + Data Analysis
Python for Data Analysis — Master Source Page 45