Unit 9: Handling data with pandas
I. Foundations of Labelled Data Handling
pandas is an open-source Python library for organizing, cleaning, transforming, and analysing structured data. Created by Wes McKinney (development began in 2008), it builds mainly on NumPy and provides labelled data structures that resemble spreadsheets and database tables.
A. Introduction to pandas
pandas makes data analysis efficient by combining labelled rows and columns with concise, vectorized operations.
- Core structures: pandas provides two principal objects:
Series: a one-dimensional labelled collection.DataFrame: a two-dimensional table composed of labelled rows and columns.
- Labels and axes: Row labels form the
index; DataFrame column labels form thecolumnsaxis. Labels may be integers, strings, dates, or other hashable values. - Data types: A column normally has one data type, such as
int64,float64,bool,string, ordatetime64[ns]; inspect types with.dtypes. - Missing values: Depending on the column type, absent data may be represented by
NaN,NaT, orpd.NA. Methods such as.isna(),.dropna(), and.fillna()handle them. - Vectorization: Expressions operate on an entire Series or DataFrame without an explicit Python loop; for example,
prices * 1.10increases every non-missing price by 10%. - Index alignment: Operations match values by labels rather than merely by position, reducing errors when datasets have differently ordered rows.
- Import convention: pandas is conventionally imported using the alias
pd.
import pandas as pd- Inspection tools: Common first checks include
.head(),.tail(),.shape,.columns,.dtypes, and.info().df.shapereturns(r, c), whereris the number of rows andcis the number of columns.df.head(3)displays the first three rows without altering the data.
II. One-Dimensional Labelled Data
A Series represents a single labelled sequence and is suitable for one variable, one table column, or a mapping from labels to values.
A. Series
A Series combines a one-dimensional array of values with an index that identifies each value.
- Construction:
pd.Series(data, index=labels, name=label)creates a Series; ifindexis omitted, pandas supplies0, 1, 2, .... - Dictionary input: Dictionary keys become index labels and dictionary values become Series values.
marks = pd.Series(
{"Asha": 82, "Bilal": 76, "Chen": 91},
name="Marks"
)- Label access:
marks.loc["Asha"]returns82;.locuses index labels. - Position access:
marks.iloc[0]returns the first value, also82;.ilocuses zero-based integer positions. - Slicing:
marks.iloc[0:2]selects positions 0 and 1, while a label slice such asmarks.loc["Asha":"Chen"]includes both endpoints when those labels occur in order. - Properties:
marks.indexreports labels,marks.dtypereports the value type, andmarks.sizereports the number of elements. - Vectorized calculation:
marks + 5adds five to every mark and returns a new Series; the original remains unchanged unless reassigned. - Boolean filtering:
marks[marks >= 80]returns only Asha and Chen because their values satisfy the condition. - Descriptive methods:
.sum(),.mean(),.min(),.max(),.count(), and.value_counts()summarize values. - Alignment behavior: Adding two Series pairs equal index labels. A label found in only one operand generally produces a missing result at that label.
- Limitation: A Series is one-dimensional; multiple related variables such as name, age, and score are more naturally stored in a DataFrame.
III. Two-Dimensional Labelled Tables
A DataFrame models rectangular data with a shared row index and named columns, although different columns may contain different data types.
A. DataFrame
A DataFrame organizes observations as rows and variables as columns, making it the central pandas structure for tabular datasets.
- Construction from a dictionary: Each dictionary key becomes a column, and equal-length lists provide its values.
students = pd.DataFrame({
"Name": ["Asha", "Bilal", "Chen"],
"Score": [82, 76, 91],
"Passed": [True, True, True]
})- Structure:
students.shapeis(3, 3): three rows and three columns. Its default index is0, 1, 2. - Column selection:
students["Score"]returns a Series.students[["Name", "Score"]]returns a DataFrame because the selector is a list.
- Row selection:
students.loc[1]selects the row labelled1, whereasstudents.iloc[1]selects the second row by position. - Combined selection:
students.loc[students["Score"] >= 80, ["Name", "Score"]]selects qualifying rows and two named columns. - Column creation:
students["Grade"] = ["B", "C", "A"]adds a fourth column. - Changing values:
students.loc[1, "Score"] = 79updates one cell identified by row label and column label. - Removing data:
students.drop(columns=["Passed"])returns a table withoutPassed; assign the result or useinplace=Trueto retain the change. - Index management:
students.set_index("Name")uses names as row labels, while.reset_index()restores a regular column and a default integer index. - Copies and views: Explicit
.copy()is useful before modifying a filtered table, avoiding ambiguous chained assignments such asdf[mask]["Score"] = 0.
IV. Ordering Rows and Labels
Sorting rearranges records for comparison, presentation, ranking, and later processing without changing the underlying values.
A. Sorting
pandas sorts either by stored values or by axis labels, and the distinction determines which method is appropriate.
-
Sorting by values:
- Single key:
df.sort_values("Score")orders rows from the smallest score to the largest. - Descending order:
ascending=Falsereverses that order. - Multiple keys:
df.sort_values(["Class", "Score"], ascending=[True, False])sorts classes alphabetically and scores within each class from highest to lowest. - Missing values:
na_position="first"or"last"controls where missing entries appear; the default is"last".
- Single key:
-
Sorting by labels:
- Row index:
df.sort_index()orders row labels. - Column labels:
df.sort_index(axis=1)orders columns;axis=1denotes the column axis. - Direction:
ascending=Falseapplies descending label order.
- Row index:
ranked = students.sort_values(
by="Score",
ascending=False,
ignore_index=True
)- Worked result: With scores
82, 76, 91,rankedorders Chen, Asha, and Bilal;ignore_index=Truereplaces the old row labels with0, 1, 2. - Non-destructive default: Sorting normally returns a new object. Use assignment, as above, to preserve the sorted result.
- Selection versus sorting:
.nlargest(2, "Score")directly obtains the two highest-scoring rows and may be clearer than sorting the entire table and taking.head(2).
V. Persistent Tabular Data
Comma-separated values files store plain-text rows, typically with one record per line and fields separated by commas.
A. Working with CSV files
pandas converts CSV text into DataFrames and writes DataFrames back to CSV through configurable input and output methods.
- Reading:
pd.read_csv("students.csv")treats the first row as column headings by default. - Path handling: The argument may be a relative path such as
"data/students.csv"or an absolute filesystem path. - Useful parameters:
usecols=["Name", "Score"]loads selected columns.dtype={"Score": "Int64"}requests a nullable integer type.na_values=["NA", "-"]treats specified tokens as missing.parse_dates=["ExamDate"]converts a date column where possible.index_col="StudentID"uses an existing column as the index.nrows=100reads only the first 100 data rows.
- Alternative separators:
sep=";"reads semicolon-delimited data even though the method remainsread_csv. - Large files:
chunksize=10_000returns an iterator of DataFrames, each containing at most 10,000 rows, reducing peak memory use. - Writing:
.to_csv()serializes a DataFrame.
students.to_csv(
"students_clean.csv",
index=False,
encoding="utf-8"
)- Index control:
index=Falseprevents pandas from writing the DataFrame index as an extra field, which is usually appropriate for a default numerical index. - Validation after loading:
.head(),.shape,.dtypes,.isna().sum(), and.duplicated().sum()expose malformed types, missing values, and repeated records. - Format limitation: CSV does not preserve pandas data types, formulas, formatting, or multiple tables; types must be inferred or specified again when the file is read.
VI. Transforming and Analysing Tables
DataFrame operations convert raw observations into selected, cleaned, summarized, or combined information while retaining row-and-column organization.
A. Operations using DataFrame
Operations using DataFrame include selection, arithmetic, missing-data treatment, aggregation, grouping, and combining related tables.
- Filtering: Conditions produce Boolean masks;
df[df["Score"] >= 80]keeps rows whose score is at least 80. - Derived columns:
df["Percent"] = df["Marks"] / df["Maximum"] * 100applies elementwise arithmetic, whereMarksis the achieved value andMaximumis the possible value. - String operations:
df["Name"].str.strip().str.title()removes surrounding spaces and applies title case to non-missing strings. - Missing-data operations:
df.dropna(subset=["Score"])removes rows lacking a score.df["Score"].fillna(df["Score"].median())replaces missing scores with the column median.
- Aggregation:
df["Score"].agg(["count", "mean", "max"])produces several summaries in one operation;countexcludes missing values. - Grouping:
df.groupby("Class")["Score"].mean()splits rows by class, calculates each group’s mean, and combines the results into a Series. - Multiple group summaries:
.agg(Mean="mean", Highest="max", Students="count")assigns meaningful names to calculated columns. - Combining tables:
pd.merge(left, right, on="StudentID", how="inner")joins rows sharingStudentID.innerkeeps matching keys only.leftkeeps every key from the left table and inserts missing values where no right-side match exists.
- Concatenation:
pd.concat([term1, term2], ignore_index=True)stacks tables vertically when their columns represent the same variables. - Duplicate handling:
df.drop_duplicates(subset=["StudentID"])retains the first row for each repeated identifier unlesskeepis changed. - Function application: Built-in vectorized methods are generally preferred, but
df["Score"].map(lambda x: x + 2)can apply a custom scalar transformation. - Performance principle: Column expressions, grouping, and vectorized string or numeric methods are normally faster and clearer than manually iterating with
forloops.
Did this save you a night before the exam?
LPU Notes is free, and it stays free. Ads cover part of the server bill. The rest comes out of a student's own pocket: the domain, the storage, and keeping the site up through the weeks everyone needs it at once.
The payment button didn't load. An ad blocker or a filtered network is the usual reason. to try again.
Nothing here is ever locked, and nothing unlocks. Chip in only if it was worth it. What it pays for →