The DataFrame: Rows and Columns
Reviewed & published by Brayan K
A DataFrame is a two-dimensional, table-like structure of labelled rows and columns — Pandas' core object, where every column is itself a Series and all columns share one common row index.
Part of the free Pandas course at LearnCodingFast — hands-on lessons with examples you run in your browser, plus practice exercises and a quick quiz.
If the Series is a single column, the DataFrame is the whole spreadsheet. This is the object you'll spend 95% of your Pandas time working with.
What You'll Learn in This Lesson
- What a DataFrame is (2-D, columns are Series)
- Build a DataFrame from a dictionary of lists
- Read the size with df.shape
- List names and labels with df.columns and df.index
- See each column's type with df.dtypes
- Select one column and get a Series back
1 What Is a DataFrame?
A DataFrame is a 2-dimensional table of data: it has labelled rows (the index) and labelled columns.
- Each column is a Series (from the previous lesson)
- All columns share the same row index
- Different columns can hold different data types
Build one from a dictionary of lists: keys are column names, each list is a column's values.
data = {
"name": ["Alice", "Bob", "Carol"],
"age": [25, 30, 35],
}
df = pd.DataFrame(data)import pandas as pd
data = {
"name": ["Alice", "Bob", "Carol"],
"age": [25, 30, 35],
"city": ["London", "Paris", "Berlin"],
}
df = pd.DataFrame(data)
print(df)
# Output:
# name age city
# 0 Alice 25 London
# 1 Bob 30 Paris
# 2 Carol 35 Berlin
# ✅ Expected output:
# name age city
# 0 Alice 25 London
# 1 Bob 30 Paris
# 2 Carol 35 Berlin2 Inspecting the Structure
Four attributes tell you everything about a DataFrame's shape and structure:
- df.shape — a (rows, columns) tuple
- df.columns — the column names
- df.index — the row labels
- df.dtypes — the data type of each column
import pandas as pd
df = pd.DataFrame({
"name": ["Alice", "Bob", "Carol"],
"age": [25, 30, 35],
"city": ["London", "Paris", "Berlin"],
})
print(df.shape) # (rows, columns)
print(df.columns) # column names
print(df.index) # row labels
print(df.dtypes) # type of each column
# Output:
# (3, 3)
# Index(['name', 'age', 'city'], dtype='object')
# RangeIndex(start=0, stop=3, step=1)
# name object
# age int64
# city object
# dtype: object
# ✅ Expected output:
# (3, 3)
# Index(['name', 'age', 'city'], dtype='object')
# RangeIndex(start=0, stop=3, step=1)
# name object
# age int64
# city object
# dtype: object3 Selecting a Column Returns a Series
Grab a single column with square brackets and the column name. The result is a Series — exactly the object from the Series lesson:
ages = df["age"]
type(ages) # <class 'pandas.core.series.Series'>Because it's a Series, every Series trick still works: df["age"].mean(), df["age"] * 2, boolean filtering, and more.
import pandas as pd
df = pd.DataFrame({
"name": ["Alice", "Bob", "Carol"],
"age": [25, 30, 35],
})
ages = df["age"] # selecting one column returns a Series
print(ages)
print(type(ages))
print("Average age:", ages.mean())
# Output:
# 0 25
# 1 30
# 2 35
# Name: age, dtype: int64
# <class 'pandas.core.series.Series'>
# Average age: 30.0
# ✅ Expected output:
# 0 25
# 1 30
# 2 35
# Name: age, dtype: int64
# <class 'pandas.core.series.Series'>
# Average age: 30.0import pandas as pd
df = pd.DataFrame({
"product": ["Pen", "Notebook", "Eraser"],
"price": [2, 5, 1],
"stock": [100, 40, 250],
})
# 🎯 YOUR TURN: print how many rows and columns this DataFrame has
# Replace ___ with the correct attribute
print(df.___)
# Expected output:
# (3, 3)📋 Quick Reference
| Attribute / Action | Returns |
|---|---|
| df.shape | (rows, columns) tuple |
| df.columns | Column names |
| df.index | Row labels |
| df.dtypes | Type of each column |
| df["col"] | A single column as a Series |
🎯 Mini Challenge: Class Roster
Build a roster and explore its structure:
- Create a DataFrame with columns name, grade, and passed
- Print its shape and dtypes
- Select the grade column and print its average
import pandas as pd
roster = pd.DataFrame({
"name": ["Ana", "Ben", "Cara", "Dan"],
"grade": [88, 72, 95, 60],
"passed": [True, True, True, False],
})
print("Shape:", roster.shape)
print(roster.dtypes)
print("Average grade:", roster["grade"].mean())
# Output:
# Shape: (4, 3)
# name object
# grade int64
# passed bool
# dtype: object
# Average grade: 78.75
# ✅ Expected output:
# Shape: (4, 3)
# name object
# grade int64
# passed bool
# dtype: object
# Average grade: 78.75❓ Frequently Asked Questions
Lesson complete — you understand the DataFrame!
You know a DataFrame is a 2-D table whose columns are Series, you can build one from a dict of lists, inspect its shape, columns, index, and dtypes, and pull out a single column as a Series.
Practice quiz
What is a pandas DataFrame?
- A one-dimensional labelled array
- A Python dictionary
- A two-dimensional table with labelled rows and columns
- A NumPy scalar
Answer: A two-dimensional table with labelled rows and columns. A DataFrame is a 2-D table of labelled rows and columns, like a spreadsheet.
What is each column of a DataFrame?
- A Series
- A list
- A dict
- A NumPy array with no index
Answer: A Series. Each column is a Series, and all columns share the same row index.
What does df['age'] return when 'age' is one column?
- A DataFrame
- A list
- A scalar
- A Series
Answer: A Series. Selecting a single column with square brackets returns a Series.
What does df.shape return?
- A list of column names
- A (rows, columns) tuple
- The number of rows only
- The dtypes
Answer: A (rows, columns) tuple. shape is a (rows, columns) tuple describing the table's size.
For a 3-row, 3-column DataFrame, what is df.shape?
- (3, 3)
- (9,)
- (3,)
- (1, 9)
Answer: (3, 3). Three rows and three columns gives the tuple (3, 3).
Which attribute lists the column names?
- df.index
- df.dtypes
- df.columns
- df.shape
Answer: df.columns. df.columns holds the column names; df.index holds the row labels.
Which attribute shows the data type of each column?
- df.shape
- df.dtypes
- df.columns
- df.values
Answer: df.dtypes. df.dtypes reports each column's dtype.
Why is df.shape written without parentheses?
- It is a method that takes no args
- Parentheses are optional
- It returns a function
- It is an attribute, not a method
Answer: It is an attribute, not a method. shape, columns, index, and dtypes are attributes — no parentheses.
Can different columns of one DataFrame hold different data types?
- No, all must match like a NumPy array
- Yes, each column can have its own dtype
- Only numeric types are allowed
- Only if they share an index
Answer: Yes, each column can have its own dtype. Unlike a NumPy array, each DataFrame column can hold a different dtype.
Because a selected column is a Series, which operation still works on df['age']?
- Nothing — Series have no methods
- Only printing
- df['age'].mean()
- Only len()
Answer: df['age'].mean(). It is a Series, so Series methods like .mean() and arithmetic still apply.
Continue this course
- Previous: The Series: Pandas' 1-D Building Block
- Next: Creating DataFrames — Build DataFrames from dicts, lists, and NumPy arrays
- Quick reference: Pandas cheat sheet
Frequently asked questions
What is a Pandas DataFrame?
A DataFrame is a two-dimensional, table-like data structure with labelled rows and columns — like a spreadsheet or SQL table. Each column is a Pandas Series, and all columns share the same row index.
Is each column of a DataFrame a Series?
Yes. Selecting a single column with df['col'] returns a Series — a one-dimensional labelled array. A DataFrame is essentially a collection of Series that all share one common index.
How do I check the size of a DataFrame?
Use df.shape, which returns a (rows, columns) tuple. df.columns lists the column names, df.index lists the row labels, and df.dtypes shows the data type of each column.
Can columns in a DataFrame have different data types?
Yes. Unlike a NumPy array, each DataFrame column can hold a different dtype — one column can be integers, another floats, another strings — which is what makes it ideal for real-world tabular data.