What is pandas?
Pandas gives you two main structures:
Series: a single column of data with an index.
DataFrame: a table of rows and columns, like an Excel sheet. Most of the time, this is what you will work with.
Install it and import it with the usual alias:
bash
pip install pandas
python
import pandas as pd
By convention, a DataFrame variable is named df, short for DataFrame.
Creating a DataFrame
You can build one from a dictionary:
df = pd.DataFrame({
"customer": ["Ann", "Ben", "Cara", "Dan", "Eve"],
"country": ["Kenya", "Uganda", "Kenya", "Tanzania", "Uganda"],
"amount": [120, 85, None, 200, 150],
"date": ["2026-01-05", "2026-01-07", "2026-01-09", "2026-01-12", "2026-01-15"],
})
Each key becomes a column, and each list holds that column's values. Note that the dictionary needs a comma after every key-value pair, which is a common cause of SyntaxError for beginners.
Loading real data
Most of the time you will read data from a file:
df = pd.read_csv("bookings.csv")
df = pd.read_excel("customers.xlsx")
If a CSV shows strange characters, try pd.read_csv("file.csv", encoding="utf-8"). If columns are merged into one, set the separator explicitly with sep=";".
First look at your data
Before doing anything else, inspect what you have:
df.head() # first 5 rows
df.tail() # last 5 rows
df.shape # (rows, columns)
df.info() # column names, types, non-null counts
df.describe() # count, mean, min, max for numeric columns
df.columns # list of column names
Make df.info() a habit. It shows at a glance which columns have the wrong type and which have missing values.
Selecting data
Select columns by name:
df["customer"] # one column (a Series)
df[["customer", "amount"]] # several columns (a DataFrame)
Select rows by position or label with iloc and loc:
python
df.iloc[0] # first row, by position
df.iloc[0:3] # first three rows
df.loc[0, "amount"] # row labelled 0, column "amount"
Filtering rows
Filtering uses a condition inside square brackets:
df[df["country"] == "Kenya"]
df[df["amount"] > 100]
df[(df["country"] == "Uganda") & (df["amount"] > 100)]
Use & for "and", | for "or", and wrap each condition in parentheses. Using the words and or or raises an error.
Handling missing values
Real data is rarely complete. Pandas shows missing values as NaN.
python
df.isnull() # True where a value is missing
df.isnull().sum() # missing count per column
You then decide what to do with them:
df.dropna() # remove rows with any missing value
df["amount"] = df["amount"].fillna(0) # replace with 0
df["amount"] = df["amount"].fillna(df["amount"].mean()) # or with the average
Which option is right depends on the data. A missing amount might mean zero, or it might mean the value is unknown, and filling it with the wrong number changes your results.
Fixing data types
Dates often load as plain text. Convert them so you can sort and group by time:
python
df["date"] = pd.to_datetime(df["date"])
df["month"] = df["date"].dt.month
Numbers stored as text can be fixed the same way:
df["amount"] = pd.to_numeric(df["amount"], errors="coerce")
errors="coerce" turns anything that can't be converted into NaN instead of crashing.
Creating and changing columns
New columns are just assignments:
python
df["amount_with_tax"] = df["amount"] * 1.16
df["is_big_order"] = df["amount"] > 150
Rename columns and drop ones you don't need:
df = df.rename(columns={"amount": "order_value"})
df = df.drop(columns=["amount_with_tax"])
Grouping and summarizing
groupby is one of the most useful tools in pandas. It splits the data into groups, applies a calculation to each, and combines the results:
python
df.groupby("country")["amount"].sum()
You can compute several things at once:
df.groupby("country").agg(
total=("amount", "sum"),
average=("amount", "mean"),
orders=("customer", "count"),
)
Sort the output to find the top performers:
python
df.groupby("country")["amount"].sum().sort_values(ascending=False)
Combining tables
Often the information you need is spread over several tables. A merge works like a SQL join:
customers = pd.DataFrame({
"customer": ["Ann", "Ben", "Cara"],
"segment": ["Retail", "Corporate", "Retail"],
})
merged = df.merge(customers, on="customer", how="left")
how="left" keeps every row from the left table.
how="inner" keeps only rows that match in both.
To stack tables with the same columns on top of each other, use pd.concat([df1, df2]).
Removing duplicates
python
df.duplicated().sum() # how many duplicate rows
df = df.drop_duplicates()
Saving your results
df.to_csv("clean_data.csv", index=False)
df.to_excel("clean_data.xlsx", index=False)
index=False stops pandas from writing the row numbers as an extra column.
A typical workflow
Most analysis projects follow roughly this order:
Load the data with read_csv or read_excel
Inspect it with head(), info() and describe()
Clean it by handling missing values, fixing types and removing duplicates
Transform it by adding columns, filtering and merging tables
Summarize it with groupby
Export or visualize the results
Common mistakes to avoid
Changing a copy without realizing it. Operations like df.dropna() return a new DataFrame, so assign the result back (df = df.dropna()).
Skipping info(). A column of numbers stored as text will silently break your sums.
Using and / or in filters. Use & and | with parentheses.
Filling missing values blindly. Check what the missing values actually mean first.
Looping over rows. Pandas is built for whole-column operations, which are much faster than for loops.
Where to go next
Use df.plot() or Matplotlib and Seaborn to visualize results
Learn pivot_table for Excel-style summaries
Try method chaining to write cleaner, more readable pipelines
Practice on real datasets from Kaggle or your own spreadsheets
Pandas feels like a lot at first, but the same few operations (load, inspect, clean, filter, group, merge) cover most real-world tasks. Practice them on a dataset that interests you, and the rest will follow.
Top comments (0)