Python Refresher
NumPy, Pandas & Matplotlib
If Python basics are your language, then NumPy, Pandas, and Matplotlib are your lab tools. They let you do fast math, clean messy data tables, and visualize patterns as charts. Every data analyst and ML engineer uses all three, every single day.
Installation
bash
pip install numpy pandas matplotlib seaborn openpyxl
openpyxl is required for reading and writing .xlsx Excel files with Pandas.
1. NumPy — Fast Numerical Arrays
NumPy (Numerical Python) replaces Python lists with ndarray objects stored in contiguous memory as a single data type. This makes bulk numerical operations 50–100x faster than pure Python loops.
Creating Arrays
python
1import numpy as np23# From a Python list4a = np.array([10, 20, 30, 40, 50])5print(a) # [10 20 30 40 50]6print(a.dtype) # int647print(a.shape) # (5,)89# Specify data type10b = np.array([1.5, 2.5, 3.5], dtype=np.float32)1112# Array of zeros / ones / uninitialized13zeros = np.zeros((3, 4)) # 3 rows, 4 columns of 0.014ones = np.ones((2, 3)) # 2 rows, 3 columns of 1.015empty = np.empty((2, 2)) # Uninitialized (random garbage values)16eye = np.eye(3) # 3x3 Identity matrix1718# Sequences19seq = np.arange(0, 10, 2) # [0 2 4 6 8] (start, stop, step)20lin = np.linspace(0, 1, 5) # [0. 0.25 0.5 0.75 1. ] (start, stop, count)2122# Random arrays23rng = np.random.default_rng(seed=42)24rand_f = rng.random((3, 3)) # Uniform [0, 1)25rand_n = rng.normal(0.0, 1.0, (100,)) # Standard normal distributionIndexing and Slicing
python
1import numpy as np23arr = np.array([10, 20, 30, 40, 50, 60])45print(arr[0]) # 10 (first element)6print(arr[-1]) # 60 (last element)7print(arr[1:4]) # [20 30 40] (slice: index 1 to 3 inclusive)8print(arr[::2]) # [10 30 50] (every 2nd element)910# 2D indexing11matrix = np.array([12 [1, 2, 3],13 [4, 5, 6],14 [7, 8, 9]15])1617print(matrix[0, :]) # [1 2 3] — first row18print(matrix[:, 1]) # [2 5 8] — second column19print(matrix[1, 2]) # 6 — row 1, col 220print(matrix[:2, :2]) # Top-left 2x2 block2122# Boolean (conditional) indexing23sensor = np.array([21.5, 35.2, 18.9, 42.0, 28.1])24hot = sensor[sensor > 30] # [35.2 42. ]25print(hot)Math Operations (Broadcasting)
python
1import numpy as np23temps_c = np.array([0.0, 20.0, 37.0, 100.0])45# Broadcasting: operation applies to every element6temps_f = (temps_c * 1.8) + 327print(temps_f) # [32. 68. 98.6 212. ]89a = np.array([1, 2, 3])10b = np.array([4, 5, 6])1112print(a + b) # [ 5 7 9]13print(a * b) # [ 4 10 18]14print(np.dot(a, b)) # 32 (dot product: 1*4 + 2*5 + 3*6)1516# Aggregation17readings = np.array([22.1, 23.5, 21.8, 24.9, 22.7])18print(readings.mean()) # 23.019print(readings.std()) # 1.0720print(readings.min()) # 21.821print(readings.max()) # 24.922print(readings.sum()) # 115.023print(np.median(readings)) # 22.724print(np.argmax(readings)) # 3 (index of max value)Reshaping and Stacking
python
1import numpy as np23a = np.arange(12) # [ 0 1 2 3 4 5 6 7 8 9 10 11]4b = a.reshape(3, 4) # Shape (3, 4)5c = a.reshape(2, 2, 3) # Shape (2, 2, 3)67# Flatten back to 1D8flat = b.flatten()910# Stack arrays together11x = np.array([1, 2, 3])12y = np.array([4, 5, 6])1314h_stack = np.hstack([x, y]) # [1 2 3 4 5 6] — side by side15v_stack = np.vstack([x, y]) # 2D: two rows1617# Transpose a matrix18m = np.array([[1, 2, 3], [4, 5, 6]])19print(m.T) # Shape (3, 2)Linear Algebra
python
1import numpy as np23A = np.array([[2, 1], [5, 3]])4B = np.array([[1, 2], [3, 4]])56print(np.dot(A, B)) # Matrix multiplication7print(np.linalg.inv(A)) # Inverse of A8print(np.linalg.det(A)) # Determinant9eigenvalues, eigenvectors = np.linalg.eig(A)10print(eigenvalues)2. Pandas — Data Tables
Pandas gives you two core data structures:
- Series — a 1D labelled array (like a single spreadsheet column)
- DataFrame — a 2D labelled table (like an entire spreadsheet)
Creating a DataFrame
python
1import pandas as pd23# From a Python dictionary4data = {5 "name": ["Alice", "Bob", "Charlie", "Diana"],6 "age": [25, 31, 28, 35],7 "temperature": [36.6, 37.1, 36.9, 38.2],8 "city": ["BLR", "HYD", "BLR", "DEL"],9}1011df = pd.DataFrame(data)12print(df)Output:
text
name age temperature city
0 Alice 25 36.6 BLR
1 Bob 31 37.1 HYD
2 Charlie 28 36.9 BLR
3 Diana 35 38.2 DEL
Inspecting a DataFrame
python
1print(df.shape) # (4, 4) — 4 rows, 4 columns2print(df.columns) # Index(['name', 'age', 'temperature', 'city'], ...)3print(df.dtypes) # Data type of each column4print(df.info()) # Column types + non-null counts5print(df.describe()) # Statistics: count, mean, std, min, max, quartiles6print(df.head(2)) # First 2 rows7print(df.tail(2)) # Last 2 rows8print(df.sample(2)) # 2 random rowsSelecting Data
python
1# Single column → Series2age_series = df["age"]34# Multiple columns → DataFrame5subset = df[["name", "temperature"]]67# Single row by index label (iloc = position-based, loc = label-based)8row0 = df.iloc[0] # First row9row_by = df.loc[0] # Row with index label 01011# Slicing rows12first_two = df.iloc[:2]1314# Boolean filtering15hot_patients = df[df["temperature"] > 37]16blr_patients = df[df["city"] == "BLR"]1718# Multiple conditions19blr_hot = df[(df["city"] == "BLR") & (df["temperature"] > 36.5)]2021# isin() for multiple values22df[df["city"].isin(["BLR", "DEL"])]Adding and Modifying Columns
python
1# New column from calculation2df["temp_f"] = (df["temperature"] * 1.8) + 3234# Conditional column using np.where5import numpy as np6df["status"] = np.where(df["temperature"] > 37, "Fever", "Normal")78# Apply a custom function to each row9df["name_upper"] = df["name"].apply(lambda x: x.upper())1011# Rename columns12df = df.rename(columns={"temperature": "temp_c"})1314# Drop a column15df = df.drop(columns=["name_upper"])Handling Missing Values
python
1import pandas as pd2import numpy as np34# Create a DataFrame with missing values5df = pd.DataFrame({6 "sensor_id": [1, 2, 3, 4, 5],7 "temp": [22.5, np.nan, 23.1, np.nan, 24.0],8 "humidity": [55.0, 60.0, np.nan, 65.0, 70.0],9})1011print(df.isna().sum()) # Count missing per column12print(df.isna().any(axis=1)) # True for rows with ANY missing value1314# Strategy 1: Drop rows with any missing value15df_dropped = df.dropna()1617# Strategy 2: Drop only if ALL values in a row are missing18df_drop_all = df.dropna(how="all")1920# Strategy 3: Fill missing with a constant21df["temp"] = df["temp"].fillna(0)2223# Strategy 4: Fill with column mean (most common for sensor data)24df["humidity"] = df["humidity"].fillna(df["humidity"].mean())2526# Strategy 5: Forward fill (use last known value)27df["temp"] = df["temp"].ffill()Grouping and Aggregating
python
1df = pd.DataFrame({2 "device": ["A", "B", "A", "B", "A"],3 "reading": [22.1, 30.5, 21.8, 31.2, 23.0],4 "hour": [8, 8, 9, 9, 10],5})67# Average reading per device8print(df.groupby("device")["reading"].mean())910# Multiple aggregations at once11stats = df.groupby("device")["reading"].agg(["mean", "std", "min", "max"])12print(stats)1314# Group by multiple columns15pivot = df.groupby(["device", "hour"])["reading"].mean().reset_index()16print(pivot)1718# Value counts — how many rows per category19print(df["device"].value_counts())Sorting and Ranking
python
1# Sort by a single column (descending)2df_sorted = df.sort_values("reading", ascending=False)34# Sort by multiple columns5df_sorted2 = df.sort_values(["device", "hour"])67# Rank values8df["rank"] = df["reading"].rank(ascending=False)3. Reading Files — CSV, JSON, Excel
CSV
python
1import pandas as pd23# Read4df = pd.read_csv("sensor_data.csv")56# Read with options7df = pd.read_csv(8 "sensor_data.csv",9 sep=",", # Separator (default: comma)10 header=0, # Row to use as column names11 index_col="timestamp", # Set a column as the index12 parse_dates=["timestamp"], # Parse this column as datetime13 usecols=["timestamp", "temperature", "humidity"], # Load only these columns14 nrows=1000, # Load only first 1000 rows (great for large files)15)1617# Write18df.to_csv("output.csv", index=False) # index=False avoids writing row numbersJSON
python
1import pandas as pd2import json34# --- Approach 1: pandas read_json ---5# Works when the file is a list of records [{...}, {...}] or nested dict6df = pd.read_json("records.json")7df.to_json("output.json", orient="records", indent=2)89# --- Approach 2: Python json module (for complex nested JSON) ---10with open("nested_data.json", "r") as f:11 raw = json.load(f)1213# Example: extract a nested field from an API response14# raw = {"status": 200, "data": [{"id": 1, "temp": 22.5}, ...]}15records = raw["data"]16df = pd.DataFrame(records)17print(df.head())1819# --- Approach 3: JSON string from an MQTT message ---20payload_str = '{"device_id": "ESP32_01", "temperature": 28.5, "humidity": 64}'21payload = json.loads(payload_str) # String → dict22print(payload["temperature"]) # 28.523json_string = json.dumps(payload) # dict → stringExcel
python
1import pandas as pd23# Read first sheet (requires openpyxl)4df = pd.read_excel("report.xlsx")56# Read a specific sheet by name7df_sheet2 = pd.read_excel("report.xlsx", sheet_name="Sales_2024")89# Read multiple sheets at once — returns a dict of DataFrames10all_sheets = pd.read_excel("report.xlsx", sheet_name=None)11for sheet_name, sheet_df in all_sheets.items():12 print(f"Sheet: {sheet_name}, Rows: {len(sheet_df)}")1314# Write to Excel (single sheet)15df.to_excel("output.xlsx", sheet_name="Results", index=False)1617# Write multiple DataFrames to different sheets18with pd.ExcelWriter("multi_sheet.xlsx", engine="openpyxl") as writer:19 df.to_excel(writer, sheet_name="Summary", index=False)20 df_sheet2.to_excel(writer, sheet_name="Details", index=False)4. Matplotlib — Charts and Graphs
Line Plot (Time Series)
python
1import matplotlib.pyplot as plt2import numpy as np34time = np.arange(0, 24) # 0 to 23 hours5temp = 25 + 5 * np.sin(time * np.pi / 12) # Simulated daily temperature curve67plt.figure(figsize=(10, 4))8plt.plot(time, temp, color="tomato", linewidth=2, label="Temperature (°C)")9plt.title("Daily Temperature Curve")10plt.xlabel("Hour of Day")11plt.ylabel("Temperature (°C)")12plt.xticks(range(0, 24, 2))13plt.legend()14plt.grid(True, linestyle="--", alpha=0.5)15plt.tight_layout()16plt.show()Bar Chart (Category Comparison)
python
1import matplotlib.pyplot as plt23devices = ["Sensor A", "Sensor B", "Sensor C", "Sensor D"]4avg_temp = [22.5, 31.2, 27.8, 19.4]5colors = ["steelblue", "tomato", "green", "orange"]67plt.figure(figsize=(8, 5))8bars = plt.bar(devices, avg_temp, color=colors, edgecolor="black", width=0.5)9plt.title("Average Temperature by Sensor")10plt.ylabel("Avg Temperature (°C)")1112# Add value labels on top of each bar13for bar in bars:14 plt.text(15 bar.get_x() + bar.get_width() / 2,16 bar.get_height() + 0.3,17 f"{bar.get_height():.1f}°C",18 ha="center", fontsize=1119 )2021plt.tight_layout()22plt.show()Histogram (Distribution)
python
1import matplotlib.pyplot as plt2import numpy as np34data = np.random.normal(loc=37.0, scale=0.5, size=1000)56plt.figure(figsize=(8, 4))7plt.hist(data, bins=30, color="steelblue", edgecolor="white", alpha=0.8)8plt.axvline(data.mean(), color="red", linestyle="--", label=f"Mean: {data.mean():.2f}")9plt.title("Distribution of Body Temperatures")10plt.xlabel("Temperature (°C)")11plt.ylabel("Frequency")12plt.legend()13plt.show()Scatter Plot (Correlation)
python
1import matplotlib.pyplot as plt2import numpy as np34np.random.seed(42)5humidity = np.random.uniform(40, 90, 200)6temperature = 15 + 0.4 * humidity + np.random.normal(0, 3, 200)78plt.figure(figsize=(8, 5))9plt.scatter(humidity, temperature, alpha=0.5, color="teal", edgecolors="none", s=30)10plt.title("Temperature vs. Humidity")11plt.xlabel("Humidity (%)")12plt.ylabel("Temperature (°C)")13plt.grid(True, linestyle="--", alpha=0.4)14plt.show()Multiple Subplots
python
1import matplotlib.pyplot as plt2import numpy as np34x = np.linspace(0, 2 * np.pi, 100)56fig, axes = plt.subplots(2, 2, figsize=(10, 8))7fig.suptitle("Signal Analysis Dashboard", fontsize=14)89axes[0, 0].plot(x, np.sin(x), color="steelblue")10axes[0, 0].set_title("Sine Wave")1112axes[0, 1].plot(x, np.cos(x), color="tomato")13axes[0, 1].set_title("Cosine Wave")1415axes[1, 0].plot(x, np.sin(x) + np.cos(x), color="green")16axes[1, 0].set_title("Sin + Cos")1718axes[1, 1].plot(x, np.sin(2 * x), color="purple")19axes[1, 1].set_title("Sin(2x)")2021plt.tight_layout()22plt.show()Seaborn — Heatmap (Correlation Matrix)
python
1import seaborn as sns2import pandas as pd3import matplotlib.pyplot as plt4import numpy as np56# Create synthetic sensor DataFrame7df = pd.DataFrame(np.random.rand(200, 4), columns=["Temp", "Humidity", "Pressure", "CO2"])89corr = df.corr()1011plt.figure(figsize=(6, 5))12sns.heatmap(13 corr, annot=True, fmt=".2f",14 cmap="coolwarm", vmin=-1, vmax=1,15 linewidths=0.516)17plt.title("Feature Correlation Matrix")18plt.show()5. End-to-End: CSV → Clean → Analyze → Plot
python
1import pandas as pd2import matplotlib.pyplot as plt34# 1. Load CSV5df = pd.read_csv("sensor_log.csv", parse_dates=["timestamp"])67# 2. Inspect8print(df.shape)9print(df.isna().sum())1011# 3. Clean12df = df.dropna(subset=["temperature", "humidity"])13df = df[df["temperature"].between(10, 50)] # Remove physically impossible readings1415# 4. Feature engineering16df["hour"] = df["timestamp"].dt.hour17df["temp_f"] = (df["temperature"] * 1.8) + 3218df["heat_index"] = df["temperature"] + 0.33 * df["humidity"] - 41920# 5. Aggregate21hourly_avg = df.groupby("hour")["temperature"].mean().reset_index()2223# 6. Export summary24hourly_avg.to_csv("hourly_summary.csv", index=False)25hourly_avg.to_excel("hourly_summary.xlsx", index=False)26hourly_avg.to_json("hourly_summary.json", orient="records", indent=2)2728# 7. Plot29plt.figure(figsize=(10, 4))30plt.plot(hourly_avg["hour"], hourly_avg["temperature"], marker="o", color="steelblue")31plt.title("Average Temperature by Hour of Day")32plt.xlabel("Hour")33plt.ylabel("Temperature (°C)")34plt.xticks(range(24))35plt.grid(True, linestyle="--", alpha=0.4)36plt.tight_layout()37plt.show()6. Quick Reference Cheatsheet
NumPy
| Operation | Code |
|---|---|
| Create array | np.array([1, 2, 3]) |
| Zeros matrix | np.zeros((m, n)) |
| Range | np.arange(start, stop, step) |
| Evenly spaced | np.linspace(start, stop, num) |
| Mean / Std | .mean() / .std() |
| Shape | .shape |
| Reshape | .reshape(m, n) |
| Boolean filter | arr[arr > 5] |
| Dot product | np.dot(a, b) |
Pandas
| Operation | Code |
|---|---|
| Read CSV | pd.read_csv("file.csv") |
| Read Excel | pd.read_excel("file.xlsx") |
| Read JSON | pd.read_json("file.json") |
| View top rows | df.head() |
| Shape | df.shape |
| Column types | df.dtypes |
| Select column | df["col"] |
| Filter rows | df[df["col"] > 5] |
| Drop NaN | df.dropna() |
| Fill NaN | df["col"].fillna(value) |
| Group + agg | df.groupby("col").mean() |
| New column | df["new"] = df["a"] + df["b"] |
| Write CSV | df.to_csv("out.csv", index=False) |
Matplotlib
| Chart | Code |
|---|---|
| Line | plt.plot(x, y) |
| Bar | plt.bar(labels, values) |
| Histogram | plt.hist(data, bins=20) |
| Scatter | plt.scatter(x, y) |
| Heatmap | sns.heatmap(corr, annot=True) |
| Subplots | fig, axes = plt.subplots(2, 2) |
| Title | plt.title("...") |
| Labels | plt.xlabel(...) / plt.ylabel(...) |
| Legend | plt.legend() |
| Grid | plt.grid(True) |
| Save | plt.savefig("chart.png", dpi=150) |
| Show | plt.show() |

