0% found this document useful (0 votes)
1 views45 pages

Python DA Master Source

The document is a comprehensive guide on Python for Data Analysis, covering essential topics such as control flow, loops, functions, data structures, and libraries like NumPy and Pandas. It includes detailed explanations, examples, and practice questions to reinforce learning. The content is structured into chapters that systematically build knowledge for the Python + Data Analysis track for students in the MDU BBA Program.

Uploaded by

aman23.ydv
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)
1 views45 pages

Python DA Master Source

The document is a comprehensive guide on Python for Data Analysis, covering essential topics such as control flow, loops, functions, data structures, and libraries like NumPy and Pandas. It includes detailed explanations, examples, and practice questions to reinforce learning. The content is structured into chapters that systematically build knowledge for the Python + Data Analysis track for students in the MDU BBA Program.

Uploaded by

aman23.ydv
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

■ 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

You might also like