Module 2 Lab Companion

BAN 6003: Data Management and Analytics Integration

Python, Pandas, and First Data Profile

Experimental pilot. Use the Ask about this lab panel (on the right, or the Ask a question button on small screens) to ask about the section you are reading, or open Common questions for saved answers. Answers explain the companion in plain language and may add general background. Each answer is labelled: instructor-approved answers were approved by your instructor; AI-generated answers are new and not yet reviewed. The notebook is still the authoritative source. Graded work (Part 6: Writing Data Quality Observations; Week 2 Assignment Notebook) is not answered for you. Questions about grades, deadlines or extensions go to your instructor.

How to use this companion

Open the Module 2 notebook and this companion at the same time. Work through the companion from top to bottom and run the matching notebook cells as you go. The notebook is the authoritative source for the lab sequence, code and required work. This companion explains what each step means, what to notice in the output and why the step matters.

Read aloud: controls and directions

Before you start: choose a reading mode, speed, and voice below. Select Read Aloud from Beginning to hear the full companion, or use Read Aloud from This Section beside any major section to continue from that point. While audio is playing, a floating control bar remains visible at the bottom of the page. Use Pause to pause temporarily, Resume to continue, and Stop to end the current reading.

Study mode reads explanations, results, tables, and notes while skipping exact Python code. Full mode also reads Python code and verbalizes common programming symbols.

Adjust text-to-speech speed from one half to two times normal speed.

Ready to read.

The read-aloud feature uses your browser's speech engine. A screen reader can access the page independently of these controls.

What is in the notebook, and what this companion adds

Notebook contentCode, official prompts, required tasks and the lab sequence come from the notebook. Each code block shows its notebook cell number.
Companion-added instructor noteThese clearly labeled notes are explanations, cautions or study advice added by this companion, many of them from the in-person lab session. They are not extra required notebook steps unless the note says so.

This companion is designed for keyboard and screen-reader access, but it is not a separate version for students who need accessibility features. It is the same learning guide for everyone. You can read it visually, use a screen reader, or use the built-in read-aloud controls while you work in the notebook.

Use either course environment

↑ Back to Lab Contents

Module 2 Learning Goals

Last week you asked where data lives. This week you ask what condition the data is in. You load a small employee table with Python and Pandas and profile it: you inspect its structure, content and quality before anyone fixes anything. By the end of the lab you should be able to:

The main idea: profile first, clean later. This week you describe problems; you do not fix them.

↑ Back to Lab Contents

Before You Start: Repository and Setup

Module 2 uses the same repository you created in Module 1 (the Weeks 1–2 template). Do not start a new one, and do not work in the instructor template.

  1. Open your own repository in GitHub Codespaces. A new Codespace usually needs 4–5 minutes the first time; reopening it is much faster.
  2. Open notebooks/Week2_lab1_python_pandas_guided_lab.ipynb. Check the file name: the folder also holds Week1_introduction_to_codespaces.ipynb and Week2_assignment.ipynb.
  3. If VS Code asks for a kernel, choose the Python environment it suggests. Then run the cells from the top. If you restart the kernel, run from the top again.

Optional local path: in GitHub Desktop, select your repository and choose Open in Visual Studio Code. Trust the folder when VS Code asks, and choose the base conda environment as the kernel. The screen looks almost the same as in Codespaces, because Codespaces also uses VS Code.

↑ Back to Lab Contents

Part 1: Python Basics You Need for This Course

This is not a full Python course. You need to run cells, read code carefully, change small pieces of example code and explain the output.

1.1 Python as a calculator

# If you run a 10 kilometer race in 43 minutes and 30 seconds,
# what is your average seconds per mile?
# 1 mile = 1.61 kilometers

seconds = 43 * 60 + 30
miles = 10 / 1.61
seconds_per_mile = seconds / miles

seconds_per_mile

1.2 Store values in variables

name = "Alice"
age = 28
salary = 95000.0
is_manager = False

print(name)
print(age)
print(salary)
print(is_manager)

print(type(name), type(age), type(salary), type(is_manager))

1.3 Comments

# This is a comment. It explains what the code does.

message1 = "It's not a bug; it's a feature."
print(message1)

1.4 Lists

departments = ["Engineering", "Marketing", "Sales"]

print(departments)
print(departments[0])  # first element
print(departments[1])  # second element

Change a list element

vector1 = [1, 2, 3]
vector1[0] = 100
print(vector1)

Multiplying a list repeats it

vector1 = [100, 2, 3]
print(vector1 * 2)

Double each element

# Loop version
new_vector = []
for x in vector1:
    new_vector.append(x * 2)
print(new_vector)

# Optional: list comprehension version
[x * 2 for x in vector1]

1.5 Dictionaries

employee = {
    "name": "Bob",
    "department": "Marketing",
    "salary": 78000
}

print(employee["name"])
print(employee["department"])
print(employee["salary"])

1.6 Errors and help()

help(print)

↑ Back to Lab Contents

Part 2: What Is Pandas?

Pandas is the main Python tool for tables. You will use it to load, inspect, filter, summarize, group, clean and transform data. Modeling comes later, with scikit-learn.

2.1 Import Pandas

import pandas as pd
print("Pandas imported successfully!")

2.2 A DataFrame and a Series

sample = pd.DataFrame({
    "employee_id": [1, 2, 3],
    "department": ["Sales", "Marketing", "Engineering"],
    "salary": [60000, 75000, 90000]
})

sample

Select one column

sample["department"]

2.3 Methods and attributes

print("DataFrame shape attribute:")
print(sample.shape)

print("DataFrame head method:")
sample.head()

↑ Back to Lab Contents

Part 3: Data Import

The file is data/employee_data.csv. A CSV file stores a table as plain text, with commas between values.

3.1 Reading a CSV without Pandas

import csv

csv_rows = []
with open("../data/employee_data.csv", "r") as file:
    csv_reader = csv.reader(file)
    for row in csv_reader:
        csv_rows.append(row)

# Show only the first 3 rows so the output is not too long
csv_rows[:3]

Reading the same file with Pandas

df = pd.read_csv("../data/employee_data.csv")
df.head()

3.2 Load the employee dataset

df = pd.read_csv("../data/employee_data.csv")
print("Data loaded successfully!")

↑ Back to Lab Contents

Part 4: First Look at the Data

4.1 First rows

df.head()
First five rows of df
employee_idfirst_namelast_namehire_datedepartmentsalaryagefull_time
0101JohnSmith4/15/22Marketing8500034.0True
1102JaneDoe8/20/21Sales9200045.0True
2103PeterJones1/2/22HR7100029.0True
3104MaryJohnson11/10/23Engineering11500038.0True
4105MikeBrown5/30/20sales89000NaNFalse

4.2 Last rows

df.tail()
Last five rows of df
employee_idfirst_namelast_namehire_datedepartmentsalaryagefull_time
8102EmilyWhite1/15/24Sales9100031.0True
9110DavidMiller7/22/19HR6800058.0True
10111SarahMoore3/12/23Marketing$91,00028.0True
11errorKevinClark2/5/24Sales8800035.0True
12113BrianHall6/18/22Engineering5900000999.0True

4.3 Dataset size

df.shape

A readable size message

num_rows, num_columns = df.shape
print(f"This dataset has {num_rows} rows and {num_columns} columns.")

4.4 Column names

df.columns

4.5 Data types and non-missing counts

df.info()

4.6 Data types only

df.dtypes

↑ Back to Lab Contents

Part 5: Data Profiling Checklist

Profiling asks six questions: How many rows and columns? What types? Any missing values? What range of numbers? Are categories consistent? Any duplicate IDs or rows? You are still diagnosing, not fixing.

5.1 Missing values

df.isna().sum()

Missing counts as percentages

missing_summary = pd.DataFrame({
    "missing_count": df.isna().sum(),
    "missing_percent": df.isna().mean() * 100
})

missing_summary
Missing-value summary (13 rows)
columnmissing_countmissing_percent
employee_id00.000000
first_name00.000000
last_name00.000000
hire_date17.692308
department00.000000
salary17.692308
age17.692308
full_time17.692308

5.2 Numerical summary with describe()

df.describe()

5.3 One statistic at a time

# Example: summary statistics for age
print("Count:", df["age"].count())
print("Mean:", df["age"].mean())
print("Median:", df["age"].median())
print("Minimum:", df["age"].min())
print("Maximum:", df["age"].max())
print("Standard deviation:", df["age"].std())

5.4 Categorical summary with value_counts()

df["department"].value_counts()

Include missing values in the count

df["department"].value_counts(dropna=False)

5.5 Unique values

df["department"].nunique()

5.6 Full duplicate rows

# Count fully duplicated rows
full_duplicate_rows = df.duplicated().sum()
print(f"Number of fully duplicated rows: {full_duplicate_rows}")

Duplicate employee IDs

# Count duplicate employee IDs
employee_id_duplicates = df["employee_id"].duplicated().sum()
print(f"Number of duplicated employee_id values after the first occurrence: {employee_id_duplicates}")

Which ID repeats?

df["employee_id"].value_counts().head(10)

↑ Back to Lab Contents

Part 6: Writing Data Quality Observations

Profiling is not finished until you write down what you found. A good observation is specific (it names the column and the number) and based on evidence (an output you can point to). Clear notes matter when you hand work to a teammate, a manager or a client.

Complete independently: Your Turn

Write 3–5 observations in the notebook cell Your Turn: Write 3–5 Observations. This is graded, so the companion does not write them for you.

What to check: each observation names a column, gives a number from an output above (a count, a percentage, a minimum or maximum), and says why it might matter later. Describe the problem; do not propose a fix yet. Do not copy the notebook's examples, which describe a different, 500-row dataset. You may also run one more check of your own, for example value_counts() on another column, and write about it.

↑ Back to Lab Contents

Part 7: Optional Challenge

These cells are optional and not graded. Run them if you have time.

Challenge 1: another categorical column

# Optional challenge 1: Choose another categorical column and run value_counts().
# Replace "department" with another column name if appropriate.

df["department"].value_counts(dropna=False)

Try first

Change "department" to another categorical column. Which column has a missing value that dropna=False will show?

  1. Count the values of full_time, including missing values.
Show sample solution for Challenge 1 (optional)

Use this only after you have made your own attempt. Compare the structure and logic, not just the final line of code. This sample solution is written by the companion; it is not part of the notebook.

df["full_time"].value_counts(dropna=False)

What it prints:

full_time
True     11
False     1
NaN       1
Name: count, dtype: int64

Without dropna=False, the NaN row disappears and the counts add up to 12, not 13.

Challenge 2: rows with any missing value

# Optional challenge 2: Show rows with at least one missing value.

df[df.isna().any(axis=1)].head()
Rows with at least one missing value
employee_idfirst_namehire_datesalaryagefull_time
4105Mike5/30/2089000NaNFalse
5106SusanNaN9500041.0True
6107Chris2023-FEB-21NaN33.0True
7108Laura9/1/2112000052.0NaN

Challenge 3: sort by salary

# Optional challenge 3: Sort by a numerical column.
# If salary is stored as text in this dataset, this may not sort the way you expect.
# That is okay! We will learn how to fix data types in Week 3.

df.sort_values("salary", ascending=False).head()

Try first

Optional extra: show both rows that share a duplicated ID, so you can compare them side by side.

  1. Use duplicated(keep=False), which marks every copy, not just the later ones.
Show sample solution for the optional extra

Use this only after you have made your own attempt. Compare the structure and logic, not just the final line of code. This sample solution is written by the companion; it is not part of the notebook.

df[df["employee_id"].duplicated(keep=False)]

What it prints:

  employee_id first_name last_name hire_date department salary   age full_time
1         102       Jane       Doe   8/20/21      Sales  92000  45.0      True
8         102      Emily     White   1/15/24      Sales  91000  31.0      True

In a large table, sorting the result by ID with .sort_values("employee_id") puts each pair next to each other.

↑ Back to Lab Contents

Week 2 Assignment Notebook

Part 8 of the guided lab looks ahead to Week 3: correcting data types, handling duplicates and missing values, and documenting each decision. Before that, there is a second notebook to complete.

Complete independently: Week2_assignment.ipynb

This notebook is graded and intentionally not solved in the companion. It uses the same employee_data.csv, so the guided lab is your reference: find the matching function there and apply it yourself.

  1. Task 0: run the cell that imports Pandas and loads the data.
  2. Task 1: show the shape, the column names, the first five rows and the last five rows.
  3. Task 2: inspect types and non-missing counts with info() and dtypes.
  4. Task 3: count missing values with isna().sum() (percentages optional).
  5. Task 4: run describe(), then at least two single statistics for one numeric column.
  6. Task 5: value_counts() for department and one more categorical column.
  7. Task 6: check full duplicate rows, duplicate employee_id values, and the most common IDs.
  8. Task 7: write 3–5 overall observations. Do not clean the data.

What to check: each # Your code here cell is filled and runs without errors, and its output is visible. Each written response uses numbers from your own outputs. A cell can show only its last result automatically, so use print() or separate cells when one task asks for several outputs.

↑ Back to Lab Contents

Common Problems

If a cell fails, read the last line of the error message first. Then find it below.

Still stuck? Post the error message and the cell number in the course Q&A discussion. Do not post your full answers.

↑ Back to Lab Contents

Save and Submit

  1. Complete the guided lab, including your observations, and the assignment notebook.
  2. Run each notebook from top to bottom and confirm there are no errors. Save both notebooks.
  3. Commit and push. In Codespaces: open Source Control, write a short message such as Complete Module 2 data profiling lab, select Commit, then Sync Changes. Or in the terminal: git add ., git commit -m "Complete Module 2 data profiling lab", git push. On the local path, use GitHub Desktop: Commit to main, then Push origin.
  4. Open your repository on GitHub in the browser, refresh it, and confirm your latest commit is there. The instructor grades the online repository, not the copy on your computer.
  5. Submit your repository link in Canvas. If the repository is private, invite zzz1990771 first.

↑ Back to Lab Contents

Lab Wrap-Up

You now have a minimum profiling toolkit:

These are the essentials, not every function you will ever need. When you need something new, check the Pandas documentation, use help(), or ask. In Week 3 you start fixing what you found today: data types, duplicates and missing values, with each decision documented.