Module 04 · Foundation

Build and inspect a DataFrame

Turn Python data into a table and inspect its structure before analysis.

Before you start: Know dictionaries, lists, Series values, and index labels.

Python loads from this site on your first run.

Each run starts with fresh data. Download any exported files before another run. Your written answers and code drafts are saved on this device; export your work to keep a backup.

M04C01 · Explore · predict · practice

Make a table from a dictionary

A DataFrame is a two-dimensional table with rows and named columns. Pass a dictionary of equally long lists to pd.DataFrame(). Each dictionary key becomes a column name. Each list position supplies the values for one row.

Read the example

data = {"Name": ["Amira", "Bilal", "Chloe"], "Age": [20, 21, 19]}
df = pd.DataFrame(data)
print(df)
print(type(df).__name__)
print("Rows and columns:", df.shape)
Verified example output · pandas 2.2.3
    Name  Age
0  Amira   20
1  Bilal   21
2  Chloe   19
DataFrame
Rows and columns: (3, 2)

Watch for this. Call pd.DataFrame(...) with a capital D and F; Python names are case-sensitive.

Your turn

Add a Campus list with RAK, Dubai, and RAK to data before building df. Print the new table and shape.

For the code check, keep these result variable names: df. Different valid approaches are welcome.

Show a hint

Add another key with a list of exactly three values.

Show one worked solution
data = {
    "Name": ["Amira", "Bilal", "Chloe"],
    "Age": [20, 21, 19],
    "Campus": ["RAK", "Dubai", "RAK"]
}
df = pd.DataFrame(data)
print(df)
print("Rows and columns:", df.shape)

The shape becomes (3, 3). The number of rows stays the same while the new key adds one data column.

Compare your explanations
  1. Read. The dictionary keys Name and Age.
  2. Predict. (3, 2): three rows and two columns.
  3. Explain. No. The index labels the rows and is separate from the two named data columns.

One quick check

In df.shape, what comes first?

What you should be able to explain. I can turn a dictionary of lists into a DataFrame.

M04C02 · Explore · predict · practice

Build a table from records

A list of dictionaries can also become a DataFrame. Each dictionary contributes a row, and pandas matches fields by their keys. If one record lacks a field, pandas marks that cell as missing. The table therefore does not require every record to contain the same keys.

Read the example

rows = [
    {"Name": "Amira", "Age": 20, "Campus": "RAK"},
    {"Name": "Bilal", "Age": 21},
    {"Name": "Chloe", "Age": 19, "Campus": "RAK"}
]
df = pd.DataFrame(rows)
print(df)
print("Missing campus:", df["Campus"].isna().sum())
Verified example output · pandas 2.2.3
    Name  Age Campus
0  Amira   20    RAK
1  Bilal   21    NaN
2  Chloe   19    RAK
Missing campus: 1

Watch for this. Missing-value display can vary with dtype and pandas version; inspect it with isna().

Your turn

Add Campus as Dubai to Bilal's record before constructing df. Check that no campus values are missing.

For the code check, keep these result variable names: df. Different valid approaches are welcome.

Show a hint

Update rows[1]["Campus"] before calling pd.DataFrame(rows).

Show one worked solution
rows = [
    {"Name": "Amira", "Age": 20, "Campus": "RAK"},
    {"Name": "Bilal", "Age": 21},
    {"Name": "Chloe", "Age": 19, "Campus": "RAK"}
]
rows[1]["Campus"] = "Dubai"
df = pd.DataFrame(rows)
print(df)
print("Missing campus:", df["Campus"].isna().sum())

Bilal now has Dubai in the Campus column. There are zero missing Campus values.

Compare your explanations
  1. Read. The second record, for Bilal.
  2. Predict. No. Bilal stays in the table with a missing Campus value.
  3. Explain. Record dictionaries name their fields, so pandas can identify the missing field for a particular row. Unequal plain lists do not state which row is missing a value.

One quick check

A record is missing one field. What can pd.DataFrame(rows) do?

What you should be able to explain. I can build a DataFrame from records and identify a missing field.

M04C03 · Explore · predict · practice

Look at the beginning and the end

The setup provides students(), a helper that returns a fresh copy of the 12-row fictional practice table. head(n) shows the first n rows and tail(n) shows the last n rows. These previews help you understand a file without printing the whole dataset. A preview alone does not prove every row is valid.

Read the example

df = students()
first = df.head(3)
last = df.tail(2)
print("First three rows:")
print(first)
print("Last two rows:")
print(last)
Verified example output · pandas 2.2.3
First three rows:
  Student_ID   Name Campus Program  Age  Study_Hours  Score  Attendance   Join_Date
0       S001  Amira    RAK      AI   20            8     88          95  2026-09-01
1       S002  Bilal  Dubai      IT   21            5     72          85  2026-09-02
2       S003  Chloe    RAK      AI   19            9     91          98  2026-09-03
Last two rows:
   Student_ID    Name Campus Program  Age  Study_Hours  Score  Attendance   Join_Date
10       S011  Khalid    RAK      AI   24            5     68          82  2026-09-11
11       S012    Lina  Dubai      IT   21            7     82          94  2026-09-12

Watch for this. head() without an argument defaults to five rows, or fewer when fewer exist.

Your turn

Show the first two rows and last three rows. Print the full table's shape to confirm previews have not removed rows.

For the code check, keep these result variable names: df, first, last. Different valid approaches are welcome.

Show a hint

Use head(2), tail(3), and df.shape.

Show one worked solution
df = students()
first = df.head(2)
last = df.tail(3)
print(first)
print(last)
print("Full shape:", df.shape)

The previews show 2 and 3 rows, while df remains a 12-row, 9-column table.

Compare your explanations
  1. Read. No. It is a helper defined in this workbook's setup to return the practice data.
  2. Predict. S011 and S012.
  3. Explain. Problems can occur in rows that the preview does not show. You also need checks across all rows.

One quick check

What does df.head(3) do?

What you should be able to explain. I can preview a dataset while preserving its full contents.

M04C04 · Explore · predict · practice

Inspect names, types, and a first summary

Attributes such as shape and columns are stored information, so they do not use parentheses. Methods such as info() perform an action and do use parentheses. info() reports column names, non-missing counts, and dtypes; describe() returns summary statistics. Text dtype labels can differ across pandas versions, so focus on what the data represent.

Read the example

df = students()
print("Columns:", df.columns.tolist())
print("Shape:", df.shape)
df.info()
summary = df[["Age", "Score"]].describe()
print(summary.round(2))
Verified example output · pandas 2.2.3
Columns: ['Student_ID', 'Name', 'Campus', 'Program', 'Age', 'Study_Hours', 'Score', 'Attendance', 'Join_Date']
Shape: (12, 9)
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 12 entries, 0 to 11
Data columns (total 9 columns):
 #   Column       Non-Null Count  Dtype 
---  ------       --------------  ----- 
 0   Student_ID   12 non-null     object
 1   Name         12 non-null     object
 2   Campus       12 non-null     object
 3   Program      12 non-null     object
 4   Age          12 non-null     int64 
 5   Study_Hours  12 non-null     int64 
 6   Score        12 non-null     int64 
 7   Attendance   12 non-null     int64 
 8   Join_Date    12 non-null     object
dtypes: int64(4), object(5)
memory usage: 996.0+ bytes
         Age  Score
count  12.00  12.00
mean   21.00  78.92
std     1.54  11.41
min    19.00  58.00
25%    20.00  71.00
50%    21.00  80.50
75%    22.00  88.25
max    24.00  95.00

Watch for this. Call df.info() directly. print(df.info()) also prints None because info() returns None.

Your turn

Inspect dtypes, then create a describe() summary for Study_Hours and Attendance only. Round it to one decimal place.

For the code check, keep these result variable names: summary. Different valid approaches are welcome.

Show a hint

Use df.dtypes and select two columns with a list inside the brackets.

Show one worked solution
df = students()
print(df.dtypes)
summary = df[["Study_Hours", "Attendance"]].describe().round(1)
print(summary)

The summary covers only Study_Hours and Attendance. Rounding changes the displayed summary, not the original data values.

Compare your explanations
  1. Read. shape is an attribute; info is a method that must be called to produce its report.
  2. Predict. 12 for each, because all 12 rows have values in both columns.
  3. Explain. It checks the full table's structure, non-missing counts, and types rather than showing one record.

One quick check

Which expression correctly accesses the table shape?

What you should be able to explain. I can inspect table structure before writing an analysis.

Further detail: official documentation for this topic.