L
LLLOS.ai
Learn
L

Chapter 3 — Data Handling Using Pandas I

Class 11 · Informatics Practices

Overview

Chapter 3 — Data Handling Using Pandas I Master Diagram

This chapter introduces Data Handling using the pandas library in Python, tailored for CBSE Class 11 Informatics Practices. It covers why pandas is used for data analysis, how it builds on Python and NumPy, and the two primary data structures — Series and DataFrame. Students learn to create, inspect and manipulate data tables, read and write common file formats (CSV, Excel), handle missing and heterogeneous data, perform basic selection, filtering, sorting and summarisation, and compute simple statistics. Emphasis is on practical skills needed to load real datasets, explore them quickly (head, tail, info, describe), and perform elementary cleaning and transformation so datasets are ready for further analysis or visualization. The chapter establishes foundational techniques and methods that are essential for data handling in later topics.

Learning Objectives

  • Define pandas Series and DataFrame and differentiate between them
  • Explain the role and advantages of pandas for data handling compared to basic Python structures
  • Import the pandas library and create Series/DataFrame from lists, dictionaries and NumPy arrays
  • Read data into a DataFrame from CSV and Excel files using read_csv and read_excel and explain common parameters (header, index_col, sep)
  • Display and interpret DataFrame metadata using head, tail, info, shape, columns and dtypes
  • Access and select data using loc, iloc, at and iat for label- and position-based indexing
  • Filter rows and columns using boolean conditions and chained selections
  • Perform basic summary statistics and aggregations using describe, mean, median, sum, min, max and value_counts

Topics in this chapter

10 topics · tap a topic title to jump straight to it.

💻1

Introduction to pandas

💻 COMPUTER SCIENCE / IT

Introduction to pandas

Key Point: Import pandas: import pandas as pd

What is pandas?
Pandas is a Python library used for data handling and analysis. It provides fast, flexible data structures (Series and DataFrame) designed to work with structured/tabular data like CSV files, Excel sheets and SQL tables. Pandas builds on NumPy and integrates well with Matplotlib and Seaborn for visualization.

Core data structures

  • Series — a one-dimensional labeled array (like a column). Example: pd.Series([10,20,30], index=['a','b','c']).
  • DataFrame — a two-dimensional labeled table with rows and columns (like a spreadsheet). Example: pd.DataFrame({'Name':['A','B'],'Marks':[85,90]}).

Getting started

  • Import: import pandas as pd
  • Read CSV: df = pd.read_csv('data.csv')
  • Basic view: df.head(), df.tail(), df.info(), df.describe()

Selecting data

  • Column access: df['column_name']
  • Row/column by labels: df.loc[2, 'column_name']
  • Row/column by integer positions: df.iloc[0:5, 0:3]
  • Filtering: df[df['marks'] > 50]

Handling missing data

  • Detect: df.isnull().sum()
  • Drop missing rows/columns: df.dropna()
  • Fill missing values: df.fillna(value)

Basic operations and aggregation

  • Summary stats: df.mean(), df.sum(), df.count()
  • Group and aggregate: df.groupby('class')['marks'].mean()
  • Sorting: df.sort_values(by='marks', ascending=False)
  • Combine tables: pd.concat([df1, df2]), df1.merge(df2, on='id', how='inner')

Input/Output
Read and write common formats: CSV, Excel, JSON. Example export: df.to_csv('out.csv', index=False).

Why pandas is useful (real-life contexts)
Pandas simplifies data cleaning, transformation, analysis and prepares data for visualization or machine learning. It is widely used in business (sales analysis), education (marks and attendance), science (weather/stocks), and many other domains.

Short code example

import pandas as pd
# load data
df = pd.read_csv('students.csv')
# view and clean
print(df.head())
print(df.isnull().sum())
df['marks'] = df['marks'].fillna(df['marks'].mean())
# group and get average
print(df.groupby('class')['marks'].mean())
# save cleaned data
df.to_csv('students_clean.csv', index=False)
📌 Examples
  • School marksheet: store student name, roll no., class, marks. Use pandas to compute class-wise average, top performers and fill any missing marks with class mean.
  • Retail sales: daily sales data with date, item, quantity, price. Use pandas to compute daily revenue, total sales by item, trend over time and identify best-selling products.
  • Attendance register: student-wise daily attendance (Present/Absent). Use pandas to calculate attendance percentage and list students below a threshold.
  • Weather data: date-wise temperature, humidity, rainfall. Use pandas to analyze monthly averages, detect missing readings and plot temperature trends.
  • Inventory management: product id, stock count, reorder level. Use pandas to find products needing reorder and to merge supplier information.
🧮 Formulas
  1. \[Import pandas: import pandas as pd\]
  2. \[Read CSV: df = pd.read_csv('file.csv')\]
  3. \[View top rows: df.head(n)\]
    \[bottom rows: df.tail(n)\]
  4. \[Get structure: df.info()\]
    \[shape: df.shape # returns (rows\]
    \[columns)\]
  5. \[Summary stats: df.describe()\]
    \[mean: df['col'].mean()\]
    \[sum: df['col'].sum()\]
  6. \[Select column: df['col']\]
    \[select multiple: df[['col1','col2']]\]
💻2

Series

💻 COMPUTER SCIENCE / IT

Series

Key Point: Create: pd.Series(data, index=..., dtype=...)

Definition: A Pandas Series is a one-dimensional labeled array capable of holding any data type (integers, floats, strings, Python objects, etc.). Each element has an associated index (labels). Think of it as a column in a spreadsheet or a 1‑D numpy array with labels.

Structure:

  • Values: the actual data (numpy array under the hood).
  • Index: labels for each value (can be numbers, strings, dates).
  • dtype: data type of the values.

Creating a Series (examples):

import pandas as pd
s1 = pd.Series([10, 20, 30])                     # default index 0,1,2
s2 = pd.Series([10, 20, 30], index=['a','b','c']) # custom index
s3 = pd.Series({'a': 10, 'b': 20})               # from dict (keys -> index)

Indexing and selection:

  • Label-based: s['a'] or s.loc['a']
  • Position-based: s.iloc[0]
  • Slicing: s[1:4] or label slices with .loc
  • Boolean indexing: s[s > 50] returns values satisfying the condition

Vectorized operations: operations apply elementwise (fast because backed by numpy). Example: s + 10, s * 2, or combining Series with aligned indexes: s1 + s2 (indexes aligned, missing labels produce NaN).

Aggregations & statistics: common methods include sum(), mean(), median(), min(), max(), std(), describe() (summary).

Missing data: missing entries are represented by NaN. Useful methods: isnull(), dropna(), fillna(value).

Index alignment & reindexing: when doing arithmetic, Series align on index labels. Use s.reindex(new_index) to change or add labels (new positions get NaN).

Useful attributes and methods: index, values, dtype, head(), tail(), unique(), value_counts(), sort_values(), sort_index().

Series vs DataFrame: A Series is a single column (1‑D). A DataFrame is 2‑D (multiple Series sharing the same index).

Small code examples (handling & plotting):

# handling missing values
s = pd.Series([10, None, 30])
s_filled = s.fillna(0)

# basic aggregation
mean_val = s.mean()

# plotting (requires matplotlib)
s.plot(kind='line')

Pedagogical note: Emphasize labeled access (.loc) vs position (.iloc) and how operations align by index — this is central to avoiding mistakes when combining Series.

📌 Examples
  • Daily maximum temperature for a week: index = dates (or day names), values = temperatures. Useful for plotting trends and computing mean temperature.
  • Student marks in Mathematics: index = student names or roll numbers, values = marks. Compute mean, highest, lowest marks; find students who scored below pass mark using boolean indexing.
  • Stock closing prices: index = trading days (dates), values = closing price. Use vectorized operations to compute daily returns: returns = prices.pct_change().
  • Survey counts for favourite fruit: create a Series from a dictionary {'Apple': 40, 'Banana': 25, 'Mango': 35} and plot a bar chart of preferences.
  • Sensor readings from a single sensor over time: use Series for analysis, detect missing readings with isnull(), fill gaps with interpolation or fillna().
🧮 Formulas
  1. \[Create: pd.Series(data\]
    \[index=...\]
    \[dtype=...)\]
  2. \[Access by label: s['label'] or s.loc['label']\]
  3. \[Access by position: s.iloc[position]\]
  4. \[Slice: s[start:stop] (position) or s.loc[start_label:end_label] (label-inclusive)\]
  5. \[Elementwise arithmetic: s + 5\]
    \[s * 2\]
    \[s1 + s2 (index-aligned)\]
  6. \[Aggregate examples: s.sum()\]
    \[s.mean()\]
    \[s.median()\]
    \[s.std()\]
    \[s.min()\]
    \[s.max()\]
    \[s.describe()\]
📊3

DataFrame

💻 COMPUTER SCIENCE / IT

DataFrame

Key Point: Select column: df['column_name']

What is a DataFrame?
A DataFrame (pandas.DataFrame) is a two-dimensional, tabular data structure in Python's pandas library. It stores data in rows and columns with labels (index and column names). Think of it like a spreadsheet or SQL table: each column can have its own data type (numeric, string, boolean, datetime).

Main components

  • Index: row labels (default 0..n-1 or custom labels)
  • Columns: column labels (names)
  • Values: the actual 2D array of data
  • dtypes: data type of each column

Common ways to create a DataFrame
From a Python dict, list of dicts, list of lists, NumPy array, CSV (pd.read_csv), Excel (pd.read_excel), SQL query, etc.

Essential methods & attributes

  • df.head(n), df.tail(n) — view first/last rows
  • df.shape — (rows, columns)
  • df.info() — summary (non-null counts and dtypes)
  • df.describe() — summary statistics for numeric cols
  • df.dtypes, df.columns, df.index
  • df['col'] or df.col — select column (Series)
  • df[['c1','c2']] — select multiple columns (DataFrame)
  • df.loc[row_label, col_label] — label-based selection
  • df.iloc[row_pos, col_pos] — position-based selection
  • df[df['col'] > value] — boolean filtering
  • df.groupby('col').agg({'num_col':'mean'}) — aggregation by groups
  • df.isnull(), df.isnull().sum(), df.dropna(), df.fillna(value) — missing data
  • df.sort_values(by='col'), df.drop(columns=['col']), df.rename(columns={'old':'new'})

Why DataFrame is useful (real-life view)
DataFrames let you load, inspect, clean, transform, analyze and visualize tabular data efficiently — from exam marks, sales records, patient data, weather logs to finance and survey responses.

Small code examples (illustrative)

# create from dict
import pandas as pd
data = {'Roll':[1,2,3], 'Name':['A','B','C'], 'Math':[78,85,90]}
df = pd.DataFrame(data)

# read from CSV
# df = pd.read_csv('students.csv')

# add column: total and percentage
df['Total'] = df[['Math']].sum(axis=1)
df['Percent'] = df['Total'] / 100 * 100  # if total marks = 100

# filter: students scoring >80 in Math
high = df[df['Math'] > 80]

# group & aggregate example (sales by region)
# sales_df.groupby('Region')['Amount'].sum()

📌 Examples
  • Create DataFrame from dict: import pandas as pd; data = {'Roll':[1,2,3],'Name':['Anu','Bhav'],'Math':[78,85,90]}; df = pd.DataFrame(data)
  • Read CSV: import pandas as pd; df = pd.read_csv('students_marks.csv'); df.head()
  • Select columns and rows: df['Name'] # single column (Series); df[['Name','Math']] # two columns (DataFrame); df.loc[1] # row with label 1; df.iloc[0:3, 0:2] # first three rows, first two cols
  • Filter and compute: passed = df[df['Percent'] >= 40]; top_scorers = df.sort_values(by='Total', ascending=False).head(5)
  • Group and aggregate: sales_by_region = sales_df.groupby('Region').agg({'Amount':'sum','OrderID':'count'}).rename(columns={'OrderID':'Orders'})
  • Handle missing values: df.isnull().sum(); df_filled = df.fillna({'Math':df['Math'].mean()}); df.dropna(subset=['Name'])
🧮 Formulas
  1. \[Select column: df['column_name']\]
  2. \[Select multiple columns: df[['col1','col2']]\]
  3. \[Row label selection: df.loc[row_label]\]
    \[label-based cell: df.loc[row_label, 'col_name']\]
  4. \[Row position selection: df.iloc[row_pos]\]
    \[cell by position: df.iloc[row_pos\]
    \[col_pos]\]
  5. \[Shape: rows\]
    \[cols = df.shape\]
  6. \[Summary stats: df['col'].mean()\]
    \[df['col'].median()\]
    \[df['col'].mode()[0]\]
    \[df['col'].std()\]
    \[df['col'].sum()\]
    \[df['col'].count()\]
💻4

Input and Output (I/O)

💻 COMPUTER SCIENCE / IT

Input and Output (I/O)

Key Point: pd.read_csv(filepath_or_buffer, sep=',', header='infer', index_col=None, usecols=None, dtype=None, parse_dates=False, na_values=None, nrows=None, skiprows=None, encoding='utf-8', chunksize=None)

What is I/O in Pandas?
Input/Output (I/O) means reading data from external sources into a Pandas DataFrame and writing DataFrame contents back to files or databases. Typical formats: CSV, Excel, JSON, SQL, HTML, and compressed files. Pandas provides high-level functions (pd.read_csv, pd.read_excel, pd.read_json, pd.read_sql, DataFrame.to_csv, to_excel, to_json, to_sql) that handle parsing, types, missing values, and performance options.

Basic workflow
1) Read: load raw data into DataFrame. 2) Inspect: df.head(), df.info(), df.describe(), df.isnull().sum(). 3) Clean/convert types: use dtype, parse_dates, converters, fillna/dropna. 4) Write: export cleaned data with options (index, header, encoding).

Key options and best practices

  • Specify encoding (encoding='utf-8' or 'latin1') to avoid errors.
  • Use parse_dates=['date_col'] to convert date strings into datetime dtype on load.
  • Set dtype or use converters to ensure numeric columns load correctly and to save memory.
  • Use usecols to load only required columns and nrows/skiprows for sampling or large files.
  • For very large files, use iterator=True with chunksize or low_memory=False and process in chunks.
  • Handle missing values during read: na_values=['', 'NA', 'n/a'] and keep_default_na options.
  • When writing, use index=False to avoid saving the DataFrame index as a separate column unless required.
  • For Excel, read/write multiple sheets using sheet_name parameter (can be name, index, or list).
  • When interacting with SQL, use SQLAlchemy engine and pd.read_sql(sql, con) / df.to_sql(name, con, if_exists='replace', index=False).

Error handling and performance tips
If read_csv raises parsing errors, try specifying delimiter (sep), quoting, engine='python', or specifying column dtypes. For memory issues, convert large integer/float columns to smaller dtypes (pd.to_numeric with downcast) and parse dates only when needed.

Common inspection commands after reading
Use df.info() to check dtypes and memory, df.head() to preview, df.describe() for summary statistics, df.dtypes to see column types, and df.isnull().sum() to find missing values.

📌 Examples
  • Read student marks from CSV and set RollNo as index: df = pd.read_csv('students.csv', index_col='RollNo', dtype={'Age': 'int64'}, na_values=['-'], parse_dates=['ExamDate'])
  • Load bank transactions with date parsing and only required columns: df = pd.read_csv('transactions.csv', usecols=['Date','Amount','Category'], parse_dates=['Date'], infer_datetime_format=True)
  • Read multiple sheets from Excel: xls = pd.read_excel('school_data.xlsx', sheet_name=['ClassA','ClassB']); df_classA = xls['ClassA']
  • Process a large CSV in chunks and write cleaned result: for chunk in pd.read_csv('big.csv', chunksize=100000): chunk = clean(chunk); chunk.to_csv('cleaned.csv', mode='a', header=not file_exists, index=False)
🧮 Formulas
  1. \[pd.read_csv(filepath_or_buffer\]
    \[sep=','\]
    \[header='infer'\]
    \[index_col=None\]
    \[usecols=None\]
    \[dtype=None\]
    \[parse_dates=False\]
    \[na_values=None\]
    \[nrows=None\]
    \[skiprows=None\]
    \[encoding='utf-8'\]
    \[chunksize=None)\]
  2. \[df.to_csv(path_or_buf\]
    \[sep=','\]
    \[index=False\]
    \[header=True\]
    \[na_rep=''\]
    \[float_format='%.2f'\]
    \[encoding='utf-8'\]
    \[compression=None)\]
  3. \[pd.read_excel(io\]
    \[sheet_name=0\]
    \[header=0\]
    \[index_col=None\]
    \[usecols=None\]
    \[dtype=None\]
    \[parse_dates=False)\]
  4. \[df.to_excel(excel_writer\]
    \[sheet_name='Sheet1'\]
    \[index=False)\]
  5. \[pd.read_json(path_or_buf\]
    \[orient='records'\]
    \[typ='frame') and df.to_json(path_or_buf\]
    \[orient='records')\]
  6. \[pd.read_sql(sql\]
    \[con\]
    \[index_col=None\]
    \[coerce_float=True\]
    \[params=None) and df.to_sql(name\]
    \[con\]
    \[if_exists='replace'\]
    \[index=False)\]
🗳️5

Indexing, Selection and Filtering

💻 COMPUTER SCIENCE / IT

Indexing, Selection and Filtering

Key Point: df['col'] -> select single column (Series)

Overview
Indexing, selection and filtering are the basic operations used to access, pick and reduce data in pandas. A DataFrame is a 2‑dimensional table with rows (index labels) and columns. A Series is a single column (1‑D) with an index.

Indexing: labels vs positions
There are two main ways to select data:

  • Label-based: use df.loc and df.at. These use the row/column labels (index names or column names).
  • Position-based: use df.iloc and df.iat. These use integer positions (0,1,2...).

Examples:

# label-based
row = df.loc['R002']            # row with index label 'R002'
value = df.loc['R002', 'Marks']

# position-based
row2 = df.iloc[1]               # second row
value2 = df.iloc[1, 2]

# fast scalar access
score = df.at['R002', 'Marks']
score2 = df.iat[1, 2]

Selection
You can select columns or subsets:

  • df['Col'] returns a Series (single column).
  • df[['C1','C2']] returns a DataFrame with selected columns.
  • Slicing rows by label: df.loc['R001':'R005'] (inclusive for labels).
  • Slicing rows by position: df.iloc[0:5] (end excluded).

Filtering (Boolean indexing)
Filtering means selecting rows that meet conditions. Conditions produce boolean Series and can be used to index the DataFrame:

# single condition
high = df[df['Marks'] > 75]

# multiple conditions (use & and | with parentheses)
good = df[(df['Marks'] > 60) & (df['Attendance'] >= 80)]

# convenient methods
subset = df[df['State'].isin(['Karnataka', 'Kerala'])]
between = df[df['Age'].between(18, 25)]
# query string form
fast = df.query('Marks > 75 and Attendance >= 80')

Setting values and chained indexing
To change values use .loc to avoid chained-indexing issues:

# safe assignment
df.loc[df['Roll'] == 10, 'Marks'] = 95
Avoid things like df[df['Roll']==10]['Marks'] = 95 because it may not change the original DataFrame reliably.

Index operations
You can set or reset indices:

df2 = df.set_index('Roll')     # set column as index
df.reset_index(inplace=True)    # move index back to column

MultiIndex (brief)
A MultiIndex (hierarchical) has multiple levels (e.g., Year and Month). Access with tuples or cross-section methods like xs.

Good practices

  • Prefer .loc/.iloc for clarity.
  • Use parentheses when combining conditions.
  • Check types and missing values before filtering.

Summary
Indexing lets you address rows/columns by label or position. Selection extracts columns or row slices. Filtering uses boolean expressions to pick rows that satisfy conditions. Together they let you inspect and prepare data for analysis.

📌 Examples
  • Student marks dataset: select students with Marks > 75 and Attendance >= 80: df[(df['Marks'] > 75) & (df['Attendance'] >= 80)]
  • Sales data: get sales of product 'A' in 2020: df.loc[df['Product'] == 'A', '2020_Sales'] or df.query("Product == 'A' and Year == 2020")
  • Temperature time series: select first 7 days using position: temps.iloc[0:7] or by date label: temps.loc['2021-06-01':'2021-06-07']
  • Employee records: find employees in departments HR or IT: df[df['Department'].isin(['HR','IT'])]
  • Age filtering: students with age between 15 and 18: df[df['Age'].between(15, 18)]
🧮 Formulas
  1. \[df['col'] -> select single column (Series)\]
  2. \[df[['c1','c2']] -> select multiple columns (DataFrame)\]
  3. \[df.loc[row_label\]
    \[col_label] -> label-based selection\]
  4. \[df.iloc[row_index\]
    \[col_index] -> position-based selection\]
  5. \[df.at[row_label\]
    \[col_label] -> fast scalar access by label\]
  6. \[df.iat[row_index\]
    \[col_index] -> fast scalar access by position\]
📊6

Handling Missing Data

💻 COMPUTER SCIENCE / IT

Handling Missing Data

Key Point: Percentage missing (column) = (count_missing / total_rows) * 100

What is missing data? Missing data (also called NA, NaN, or null) occurs when no value is stored for a variable in a dataset. In Pandas these appear as NaN (float), None (Python), or as placeholder values like -1 or "unknown".

Why handle missing data? Missing values can bias results, break algorithms, or produce wrong statistics (means, correlations). Proper handling preserves data quality for analysis and machine learning.

Missingness patterns (helps choose strategy):

  • MCAR (Missing Completely At Random): missingness unrelated to data — safe to drop sometimes.
  • MAR (Missing At Random): missingness related to observed data — imputation using other columns may work.
  • MNAR (Missing Not At Random): missingness depends on unobserved values — hardest to handle and needs domain knowledge.

Detecting missing data (Pandas): use df.isnull(), df.isna(), df.notnull(), df.info(), df.isnull().sum(). Visual checks with plots are recommended.

Common handling methods (with Pandas functions):

  • Remove rows/columns: df.dropna(axis=0 or 1, how='any' or 'all', thresh=..., subset=[...]). Use when missingness is small or whole column useless.
  • Replace/Impute with constants: df.fillna(value) — e.g., 0 or 'unknown'.
  • Statistical imputation: replace with column mean, median, or mode: df['col'].fillna(df['col'].mean()).
  • Group-wise imputation: replace using group aggregates: df['col'] = df.groupby('group')['col'].transform(lambda x: x.fillna(x.mean())).
  • Forward/Backward fill for ordered data: df.fillna(method='ffill') or method='bfill'.
  • Interpolation (linear/time): df['col'].interpolate(method='linear' or 'time') — good for time series.
  • Replace placeholders: first convert placeholders to NaN: df.replace({'unknown': np.nan, -1: np.nan}, inplace=True), then handle them.

Best practices:

  • Always explore and visualise missingness before choosing a method.
  • Prefer simple methods first (drop if few missing). Use imputation if dropping would bias results or lose too much data.
  • Use domain knowledge: e.g., missing test scores might mean 'absent'.
  • When imputing, consider preserving variance (multiple imputation or model-based imputation for advanced use).
  • Document every replacement or deletion and, if possible, keep original data copy.

Example Pandas snippets:

# count missing per column
missing = df.isnull().sum()

# drop rows with any missing value
df.dropna(axis=0, how='any', inplace=True)

# fill numeric column with mean
df['age'] = df['age'].fillna(df['age'].mean())

# forward fill time series
df['temp'] = df['temp'].fillna(method='ffill')

# linear interpolate
df['value'] = df['value'].interpolate(method='linear')

# group-wise mean imputation
df['score'] = df.groupby('class')['score'].transform(lambda x: x.fillna(x.mean()))

Handling missing data properly ensures analyses are reliable and interpretable.

📌 Examples
  • Survey responses: respondents skip the age question. Solution: compute percentage missing, then impute using median age (robust to outliers) or leave as a separate category if 'unknown' matters.
  • Temperature sensor network: occasional dropped readings in time series. Solution: use forward-fill for short gaps, linear interpolation for gradual changes, or model-based imputation for long gaps.
  • Student marks: some students have missing marks for a subject. Solution: impute using class average or group-wise mean (by section) or investigate if missing = absent (treat separately).
  • Hospital records: missing blood pressure values correlated with severity (MNAR). Solution: do not blindly impute—consult clinicians, consider flagging missingness as a feature, or use advanced methods.
  • Retail sales data: missing sales on holidays recorded as 0 vs missing. Replace placeholder values (e.g., -1) with NaN then choose drop or impute consistently.
🧮 Formulas
  1. \[Percentage missing (column) = (count_missing / total_rows) * 100\]
  2. \[Mean (for imputation) = (1/n) * Σ xi for non-missing xi\]
  3. \[Median: middle value after sorting (robust to outliers) — use when distribution skewed\]
  4. \[Mode: most frequent value (useful for categorical imputation)\]
  5. \[Group-wise imputation: x_imputed = x if not missing else mean(group) where mean(group) = (1/m) * Σ x_in_group\]
  6. \[Linear interpolation between two known points (t1,y1) and (t2,y2) for time t: y = y1 + (y2 - y1) * (t - t1) / (t2 - t1)\]
📊7

Data wrangling and transformation

💻 COMPUTER SCIENCE / IT

Data wrangling and transformation

Key Point: Min–Max normalization: x' = (x - min(X)) / (max(X) - min(X)) — scales values to [0,1].

What is Data Wrangling and Transformation?
Data wrangling (also called data cleaning or data munging) is the process of inspecting, cleaning, restructuring and enriching raw data so it becomes suitable for analysis. Transformation refers to changing the shape, type or scale of data (e.g., converting strings to dates, normalizing numeric values, pivoting tables).

Typical workflow / steps

  • Inspect: Understand data with df.info(), df.head(), df.describe() and check missing values and types.
  • Clean: Handle missing values (df.dropna(), df.fillna()), remove duplicates (df.drop_duplicates()), correct typos (df.replace()).
  • Convert types: Convert columns to correct types, e.g. pd.to_datetime(), df['col'] = df['col'].astype('int').
  • Transform / reshape: Filter and sort (df[df.col > value], df.sort_values()), create new columns (df['new'] = ...), group and aggregate (df.groupby().agg()), reshape with pivot_table or melt.
  • Encode & scale: Convert categorical variables to numeric (one-hot encoding via pd.get_dummies() or label encoding), scale numeric features (min-max or z-score).
  • Validate & export: Re-check summaries and save cleaned data (df.to_csv()).

Common pandas operations (quick reference)

  • Inspect: df.head(), df.info(), df.describe(), df.isnull().sum()
  • Missing values: df.dropna(), df.fillna(value), df['col'].fillna(df['col'].median())
  • Duplicates: df.drop_duplicates()
  • Type conversion: pd.to_datetime(df['date']), df['col'].astype('int')
  • String ops: df['name'].str.lower(), df['col'].str.replace()
  • Combine tables: pd.concat([df1,df2]), pd.merge(df1,df2, on='key', how='inner')
  • Reshape: df.pivot_table(index='A', columns='B', values='C', aggfunc='sum'), pd.melt(df)
  • Group & aggregate: df.groupby('col').agg({'sales':'sum','qty':'mean'})
  • Encoding: pd.get_dummies(df['category'])

Why it matters
Analytical models and visualizations require correct types, no obvious errors, and appropriate scales. Good wrangling reduces bias, prevents errors and makes insights reliable.

📌 Examples
  • Student marks dataset: Remove duplicate rows, fill missing marks in a subject with the subject median, convert roll number to integer, calculate total and percentage columns, and sort by percentage to list top performers.
  • Daily sales data from multiple stores: Combine CSVs with the same columns using pd.concat(), convert the date column with pd.to_datetime(), extract month and weekday, group by month and store to get monthly sales summary, and fill missing prices with the median price for the product.
  • Survey responses with categorical answers: Standardize typos in responses (e.g., 'Yes', 'yes', 'Y' → 'Yes'), encode categories using one-hot encoding (pd.get_dummies) before feeding into models, and drop respondents with large amounts of missing data.
  • Weather time series: Parse timestamp strings to datetime, set datetime as index (<code>df.set_index('date')</code>), resample to weekly/monthly means (<code>df.resample('M').mean()</code>), and compute a 7-day rolling average to smooth daily noise.
  • Merging customer and transaction tables: Use pd.merge(customers, transactions, on='customer_id', how='left') to attach customer details to each transaction; then aggregate transactions per customer using groupby and sum.
🧮 Formulas
  1. \[Min–Max normalization: x' = (x - min(X)) / (max(X) - min(X)) — scales values to [0,1].\]
  2. \[Z-score (standardization): z = (x - μ) / σ\]
    \[where μ is mean and σ is standard deviation.\]
  3. \[Percentage change: %Δ = (current - previous) / previous × 100.\]
  4. \[Rolling mean (window of n): rolling_mean_t = (x_t + x_{t-1} + ... + x_{t-n+1}) / n.\]
  5. \[Imputation by mean/median/mode: filled_value = mean(column) or median(column) or mode(column).\]
  6. \[Aggregation examples: group_sum = df.groupby('key')['value'].sum()\]
    \[group_mean = df.groupby('key')['value'].mean().\]
📊8

Basic statistics and aggregation

💻 COMPUTER SCIENCE / IT

Basic statistics and aggregation

Key Point: Mean (arithmetic average): mean = (x1 + x2 + ... + xn) / n

What this topic covers
Basic statistics and aggregation using Pandas teach how to compute summary numbers (central tendency, spread, counts) and how to combine rows to produce aggregate results (sums, means, counts) — useful for understanding and summarizing datasets.

Key statistical concepts

  • Central tendency: mean (average), median (middle value), mode (most frequent).
  • Dispersion: range, variance, standard deviation, interquartile range (IQR).
  • Distribution summary: percentiles/quantiles and five-number summary (min, Q1, median, Q3, max).

Pandas objects and methods

  • Series and DataFrame provide built-in summary methods: mean(), median(), mode(), std(), var(), min(), max(), sum(), count().
  • describe() returns a compact summary (count, mean, std, min, 25%, 50%, 75%, max) for numeric columns.
  • value_counts() counts occurrences of categorical values (use normalize=True for proportions).
  • Aggregation (single or multiple functions) using agg() or aggregate() on a Series/DataFrame: e.g. df['score'].agg(['mean','std']).
  • Grouping with groupby() to compute aggregates per group: df.groupby('class')['marks'].mean() or multiple aggregations: df.groupby('city').agg({'sales':'sum','profit':'mean'}).
  • Pivot-like aggregation with pivot_table() to create cross-tab summaries: df.pivot_table(values='sales', index='region', columns='month', aggfunc='sum', fill_value=0).

Important parameters

  • axis: axis=0 (default) aggregates down columns, axis=1 aggregates across columns (rows-wise).
  • skipna (default True): ignore NaNs in calculations; use dropna / fillna if you need specific handling.
  • numeric_only: include only numeric columns in some summary methods.

Example code patterns

# summary for numeric columns
print(df.describe())

# single-statistic for a column
mean_marks = df['marks'].mean()

# multiple aggregations on a column
df['marks'].agg(['mean','median','std'])

# groupwise aggregation
df.groupby('class')['marks'].agg(['count','mean','std'])

# custom aggregation per column
df.groupby('product').agg({'sales':'sum','discount':'mean'})

# pivot table
pd.pivot_table(df, values='sales', index='store', columns='month', aggfunc='sum', fill_value=0)

# counts of categories
df['response'].value_counts()

# relative frequencies
df['response'].value_counts(normalize=True)

Handling missing values before aggregation
Missing data can bias results. Options: df.dropna() to remove rows, or df.fillna(value) to impute. Many Pandas methods ignore NaNs by default (skipna=True).

Interpreting results
Use mean for symmetric numeric data, median for skewed distributions, and IQR or boxplots to detect outliers. Grouped aggregates reveal patterns across categories (e.g., which region has higher average sales).

📌 Examples
  • Class test scores: Use df['score'].mean(), df['score'].std(), df['score'].median() to summarize performance; use df.groupby('section')['score'].mean() to compare sections.
  • Sales data: Compute total sales per region using df.groupby('region')['sales'].sum(), and average order value using df.groupby('region')['order_value'].mean(). Create a pivot table to show monthly sales by product.
  • Survey responses: Use df['choice'].value_counts() to get counts of each option and value_counts(normalize=True) for percentages.
  • Temperature readings: df['temp'].describe() gives min, max, mean, std and quartiles; use IQR to identify outlier days.
🧮 Formulas
  1. \[Mean (arithmetic average): mean = (x1 + x2 + ... + xn) / n\]
  2. \[Median: middle value after sorting\]
    \[if n is even\]
    \[median = average of two middle values\]
  3. \[Mode: most frequent value in the dataset\]
  4. \[Population variance: σ² = (1/n) * Σ (xi - μ)²\]
  5. \[Sample variance (Pandas default uses ddof=1): s² = (1/(n-1)) * Σ (xi - x̄)²\]
  6. \[Standard deviation: σ or s = sqrt(variance)\]
📊9

Text and categorical data handling (intro)

💻 COMPUTER SCIENCE / IT

Text and categorical data handling (intro)

Key Point: Frequency of a category: f_i = count(category_i)

What are text and categorical data?

Text data (string data) are free-form sequences of characters such as names, comments, addresses, product reviews, tweets. They are often unstructured and require cleaning and tokenization before analysis.

Categorical data represent variables that take values from a limited set of discrete categories. Categories can be nominal (no intrinsic order, e.g., gender, colour) or ordinal (ordered categories, e.g., education level, rating: low/medium/high).

How pandas handles them

  • Text columns usually have dtype object or string. Pandas provides the .str accessor to perform vectorised string operations: lowercasing, trimming, contains, split, replace, length, extract with regex.
  • Categorical columns can be converted to dtype category using astype('category') or pd.Categorical. category dtype stores a list of categories and optional order, reduces memory use, and enables efficient operations like .cat.codes, .cat.categories, and reordering.

Common tasks

  • Cleaning text: trim whitespace, lowercasing, remove punctuation, correct common misspellings.
  • Tokenization and simple text features: word counts, character counts, presence of keywords, extracting hashtags or mentions.
  • Converting text to categorical: map repeated text values to categories; reduce cardinality by grouping rare values into an "Other" category.
  • Encoding categories for modelling: label encoding (integer codes) for ordinal data, one-hot encoding (dummy variables) for nominal data using pd.get_dummies or pandas categorical methods.
  • Summarising categories: value_counts, groupby + aggregation, proportion and percentage calculations.

Why these matter

Proper handling of text and categorical data is essential for accurate summaries, efficient storage, correct model inputs, and meaningful visualizations. Cleaning reduces noise, while appropriate encoding preserves important information (order for ordinal data, distinct flags for nominal data).

📌 Examples
  • Survey data: column 'Preferred_transport' with values 'Car', 'Bus', 'Train', 'Cycle' is categorical (nominal). Use df['Preferred_transport'].value_counts() to see frequencies.
  • Ratings: column 'Satisfaction' with values 'Low', 'Medium', 'High' is ordinal. Convert to ordered category and map to numbers for modelling: {'Low':1, 'Medium':2, 'High':3}.
  • User comments: column 'Review_text' contains sentences. Use df['Review_text'].str.lower().str.replace('[^a-z0-9 ]', '') to normalise, then split into words to count common words.
  • Product categories with many distinct names can be grouped: treat categories appearing less than a threshold as 'Other' to reduce cardinality before one-hot encoding.
🧮 Formulas
  1. \[Frequency of a category: f_i = count(category_i)\]
  2. \[Proportion of a category: p_i = f_i / N (where N is total non-missing observations)\]
  3. \[Percentage: %_i = 100 * p_i\]
  4. \[Mode (most common category): mode = category with max f_i\]
  5. \[One-hot encoding: for k distinct categories create k binary columns\]
    \[for a row with category_j\]
    \[dummy_j = 1 and others = 0\]
  6. \[Label/ordinal encoding: map categories to integers using an ordered mapping\]
    \[e.g.\]
    \[mapped_value = mapping[category]\]
💻10

Utility functions and inspection

📐 MATHEMATICAL FORMULA / THEOREM

Utility functions and inspection

Key Point: Missing percent per column = df.isnull().sum() / len(df) * 100

Overview: Utility functions and inspection in pandas are the set of methods used to load, examine and get a quick summary of a DataFrame so you understand its shape, types, missing values and basic statistics before further cleaning or analysis.

Common inspection methods (what they show):

  • pd.read_csv(...) — read CSV into a DataFrame.
  • df.head(n) / df.tail(n) — first/last n rows (quick peek).
  • df.sample(n) — random sample of rows.
  • df.shape — tuple (rows, columns).
  • df.columns — list/Index of column names.
  • df.index — row index range or labels.
  • df.dtypes — data type of each column (int, float, object, datetime, etc.).
  • df.info() — concise summary: index, dtypes, non-null counts and memory usage.
  • df.describe() — summary statistics for numeric columns (count, mean, std, min, 25%, 50%, 75%, max); df.describe(include='all') includes non-numeric summaries.
  • df.isnull().sum() — count of missing values per column.
  • df.nunique() — number of unique values per column.
  • df.value_counts() — frequency counts for a Series (useful for categorical columns).
  • df.duplicated() / df.drop_duplicates() — find/remove duplicate rows.
  • df.memory_usage(deep=True) — memory used by each column (helpful for optimization).

Why inspect first? Before cleaning or plotting, inspection tells you:

  • How many rows/columns you have (df.shape)
  • Which columns are numeric vs categorical (df.dtypes)
  • Whether there are missing values and where (df.isnull().sum())
  • Presence of duplicates or unexpected values (df.nunique(), value_counts)
  • Basic distribution of numeric variables (df.describe())

Short example workflow (typical first steps):

  1. Load: df = pd.read_csv('file.csv')
  2. Peek: df.head() and df.sample(5)
  3. Summary: df.info() and df.describe()
  4. Missing/uniqueness: df.isnull().sum(), df.nunique()
  5. Frequencies: df['col'].value_counts()

Typical code snippets (as HTML code examples):

# load and inspect
import pandas as pd

df = pd.read_csv('students.csv')
print(df.shape)          # (rows, cols)
print(df.columns)
print(df.dtypes)
print(df.head())

# quick summary
print(df.info())
print(df.describe())

# missing and duplicates
print(df.isnull().sum())
print(df.duplicated().sum())

Best practices:

  • Always inspect data right after loading — it avoids surprises later.
  • Use df.info() to spot columns loaded as object that should be numeric or datetime; convert them with pd.to_datetime() or df['col'] = df['col'].astype('int').
  • Check missing value percentages before deciding how to impute or drop rows/columns.
  • For large datasets use df.head(), df.sample() and df.info(memory_usage=True) to limit expensive operations.

How inspection informs next steps: If df.describe() shows extreme min/max or large std, you may need outlier handling. If df.isnull().sum() shows many nulls in a column, consider dropping or imputing. If dtypes are wrong, convert them.

📌 Examples
  • Student marks dataset (students.csv): - Load: df = pd.read_csv('students.csv') - Peek: df.head() - Check types and missing: df.info(); df.isnull().sum() - Get summary stats for marks: df['math_marks'].describe(); mean = df['math_marks'].mean()
  • Store sales dataset (sales.csv) with date, product, quantity, price: - df['date'] = pd.to_datetime(df['date']) # convert to datetime - Check unique products: df['product'].nunique(); product_counts = df['product'].value_counts() - Check memory before large ops: df.memory_usage(deep=True)
  • Weather dataset (weather.csv) with temperature, humidity: - Use df.describe() to see distribution of temperature - Find missing data pattern: df.isnull().sum(); visualize missing with a heatmap - Check duplicates: df.duplicated().sum()
🧮 Formulas
  1. \[Missing percent per column = df.isnull().sum() / len(df) * 100\]
  2. \[Number of rows\]
    \[columns = df.shape # returns (rows\]
    \[columns)\]
  3. \[Mean of a column = df['col'].mean()\]
  4. \[Median of a column = df['col'].median()\]
  5. \[Mode of a column = df['col'].mode()[0] # first mode\]
  6. \[Std deviation = df['col'].std()\]
    \[Variance = df['col'].var()\]

Key Concepts

Pandas
A Python library providing data structures and functions for data manipulation and analysis, especially tabular data.
Series
A one-dimensional labeled array capable of holding any data type; like a column in a table.
DataFrame
A two-dimensional labeled data structure with columns of potentially different types; like a spreadsheet or SQL table.
Index
Labels that identify rows (or columns) in a Series or DataFrame, enabling fast lookups and alignment.
dtype
The data type of elements in a Series or DataFrame column (e.g., int64, float64, object).
read_csv
Function to read a CSV file into a DataFrame, with many options for parsing and handling data.
head
Method that returns the first n rows of a DataFrame (default n=5). Useful for quick inspection.
tail
Method that returns the last n rows of a DataFrame (default n=5).
info
Method that shows a concise summary of a DataFrame: index, columns, non-null counts and dtypes.
describe
Method that generates descriptive statistics (count, mean, std, min, quartiles, max) for numeric columns.
columns
Attribute that lists or sets the column labels of a DataFrame.
loc
Label-based indexer to select rows and columns by labels or boolean arrays.
iloc
Integer position–based indexer to select rows and columns by integer location.
isnull
Function/method that detects missing values (NaN) and returns a boolean mask.
dropna
Method to remove rows or columns with missing values, with options to control how much missingness to allow.
fillna
Method to fill missing values with a specified value or using a method (e.g., forward fill).
value_counts
Method for a Series that returns counts of unique values, sorted by frequency.
apply
Method to apply a function along an axis (rows or columns) of a DataFrame or on a Series.
merge
Function to join two DataFrames based on common columns or indices (similar to SQL joins).
sort_values
Method to sort a DataFrame by one or more column values, ascending or descending.

Practice Questions

  1. Define a pandas Series and a DataFrame, and state one key difference. / पांडास Series और DataFrame को परिभाषित कीजिए, और एक मुख्य अंतर बताइए।
    Show answer

    A Series is a one-dimensional labeled array (like a single column), while a DataFrame is a two-dimensional labeled table of rows and columns; the key difference is that a Series is 1-D and a DataFrame is 2-D (multiple Series sharing one index). / Series एक-आयामी लेबल युक्त सरणी है (एक स्तंभ जैसी), जबकि DataFrame पंक्तियों और स्तंभों की दो-आयामी लेबल युक्त सारणी है; मुख्य अंतर यह है कि Series 1-आयामी और DataFrame 2-आयामी (एक ही इंडेक्स साझा करने वाली कई Series) है।

  2. What is the difference between loc and iloc when selecting data? / डेटा चयन करते समय loc और iloc में क्या अंतर है?
    Show answer

    loc selects data by label (row/column names), e.g., df.loc['R002','Marks'], while iloc selects by integer position, e.g., df.iloc[1,2]; loc label slicing is inclusive whereas iloc position slicing excludes the end. / loc डेटा को लेबल (पंक्ति/स्तंभ नाम) से चुनता है, जैसे df.loc['R002','Marks'], जबकि iloc पूर्णांक स्थिति से चुनता है, जैसे df.iloc[1,2]; loc का लेबल स्लाइसिंग समावेशी है जबकि iloc स्थिति स्लाइसिंग अंत को छोड़ देता है।

  3. Write the pandas code to read a CSV file 'students.csv' and display its first 5 rows. / 'students.csv' CSV फ़ाइल पढ़ने और इसकी पहली 5 पंक्तियाँ दिखाने के लिए पांडास कोड लिखिए।
    Show answer

    import pandas as pd; df = pd.read_csv('students.csv'); print(df.head()) — head() returns the first 5 rows by default for quick inspection. / import pandas as pd; df = pd.read_csv('students.csv'); print(df.head()) — head() त्वरित निरीक्षण के लिए डिफ़ॉल्ट रूप से पहली 5 पंक्तियाँ लौटाता है।

  4. How do you detect and then fill missing values in a numeric column with its mean? / आप किसी संख्यात्मक स्तंभ में अनुपस्थित मानों का पता कैसे लगाते हैं और फिर उन्हें उसके माध्य से कैसे भरते हैं?
    Show answer

    Detect with df.isnull().sum() to count NaNs per column, then fill using df['marks'] = df['marks'].fillna(df['marks'].mean()) to replace missing marks with the column mean. / df.isnull().sum() से प्रत्येक स्तंभ में NaN गिनकर पता लगाएँ, फिर df['marks'] = df['marks'].fillna(df['marks'].mean()) से अनुपस्थित अंकों को स्तंभ माध्य से बदलें।

  5. Write a boolean filter to select students with Marks > 75 and Attendance >= 80. / Marks > 75 और Attendance >= 80 वाले छात्रों को चुनने के लिए एक बूलियन फ़िल्टर लिखिए।
    Show answer

    df[(df['Marks'] > 75) & (df['Attendance'] >= 80)] — each condition is parenthesised and combined with & for element-wise AND. / df[(df['Marks'] > 75) & (df['Attendance'] >= 80)] — प्रत्येक शर्त कोष्ठक में रखी जाती है और तत्व-वार AND के लिए & से जोड़ी जाती है।

  6. Which methods would you use to inspect a DataFrame's structure, and what does each show? / DataFrame की संरचना का निरीक्षण करने के लिए आप कौन-सी विधियाँ प्रयोग करेंगे, और प्रत्येक क्या दिखाती है?
    Show answer

    df.shape gives (rows, columns), df.info() shows dtypes and non-null counts, df.describe() gives numeric summary statistics, and df.dtypes shows each column's data type. / df.shape (पंक्तियाँ, स्तंभ) देता है, df.info() डेटा-प्रकार और गैर-शून्य गणना दिखाता है, df.describe() संख्यात्मक सारांश सांख्यिकी देता है, और df.dtypes प्रत्येक स्तंभ का डेटा-प्रकार दिखाता है।

  7. Explain index alignment when adding two Series with partly different index labels. / आंशिक रूप से भिन्न इंडेक्स लेबल वाली दो Series जोड़ते समय इंडेक्स संरेखण समझाइए।
    Show answer

    When two Series are added, pandas aligns them by index labels and adds values for matching labels; labels present in only one Series produce NaN in the result. / जब दो Series जोड़ी जाती हैं, पांडास उन्हें इंडेक्स लेबल द्वारा संरेखित करता है और मिलते-जुलते लेबल के मानों को जोड़ता है; केवल एक Series में मौजूद लेबल परिणाम में NaN उत्पन्न करते हैं।

  8. Use groupby to find the class-wise average marks, and state why aggregation is useful. / कक्षा-वार औसत अंक ज्ञात करने के लिए groupby का उपयोग कीजिए, और बताइए कि एकत्रीकरण उपयोगी क्यों है।
    Show answer

    df.groupby('class')['marks'].mean() groups rows by class and computes the average marks per class; aggregation is useful because it summarises large data into meaningful per-group insights for comparison. / df.groupby('class')['marks'].mean() पंक्तियों को कक्षा द्वारा समूहित करता है और प्रति कक्षा औसत अंक की गणना करता है; एकत्रीकरण उपयोगी है क्योंकि यह बड़े डेटा को तुलना हेतु सार्थक प्रति-समूह अंतर्दृष्टि में सारांशित करता है।

Related Laws & Principles

Explore all

Foundational laws & principles connected to this chapter — tap to open in the Laws Explorer.

Loading related laws…
Sourced from 153 content files · LLOS Learn · browse all chapters