Creating DataFrames
Reviewed & published by Brayan K
Creating a DataFrame means turning raw Python data — dictionaries, lists, or NumPy arrays — into a labelled table using the pd.DataFrame(...) constructor, choosing the input shape that best matches your data.
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.
Real data arrives in many shapes. In this lesson you'll learn every common way to hand data to Pandas and get a clean table back.
What You'll Learn in This Lesson
- Build from a dictionary of lists (column-oriented)
- Build from a list of dictionaries (row-oriented)
- Build from a list of lists with columns=
- Build from a NumPy array
- Set a custom row index
- Pick the right input shape for your data
1 Dict of Lists vs List of Dicts
The two most common inputs map onto how your data is organised:
📦 Dict of lists — column-oriented
Each key is a column, each list is that column's values.
📋 List of dicts — row-oriented
Each dict is one row; keys become the column names.
import pandas as pd
# Method 1: dict of lists (column-oriented)
by_columns = pd.DataFrame({
"name": ["Alice", "Bob"],
"age": [25, 30],
})
# Method 2: list of dicts (row-oriented) — same result
by_rows = pd.DataFrame([
{"name": "Alice", "age": 25},
{"name": "Bob", "age": 30},
])
print(by_columns)
print(by_rows.equals(by_columns)) # True — identical tables
# Output:
# name age
# 0 Alice 25
# 1 Bob 30
# True
# ✅ Expected output:
# name age
# 0 Alice 25
# 1 Bob 30
# True2 List of Lists with columns=
If your data is a plain grid of values — a list where each inner list is one row — pass it directly and name the columns with columns=:
rows = [
["Alice", 25],
["Bob", 30],
]
df = pd.DataFrame(rows, columns=["name", "age"])import pandas as pd
# A grid of values — one inner list per row
rows = [
["Alice", 25, "London"],
["Bob", 30, "Paris"],
["Carol", 35, "Berlin"],
]
df = pd.DataFrame(rows, columns=["name", "age", "city"])
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 Berlin3 From a NumPy Array (and Custom Index)
Numerical data often starts life as a NumPy array. Pass the 2-D array as the first argument, then label the rows and columns with index= and columns=:
arr = np.array([[1, 2], [3, 4]])
df = pd.DataFrame(arr, columns=["a", "b"], index=["r1", "r2"])The index= argument sets custom row labels instead of the default 0, 1, 2, ....
import pandas as pd
import numpy as np
# A 2-D NumPy array of numbers
arr = np.array([
[85, 90],
[78, 88],
[92, 95],
])
# Label rows with index= and columns with columns=
df = pd.DataFrame(arr, columns=["math", "science"], index=["Ana", "Ben", "Cara"])
print(df)
# Output:
# math science
# Ana 85 90
# Ben 78 88
# Cara 92 95
# ✅ Expected output:
# math science
# Ana 85 90
# Ben 78 88
# Cara 92 95import pandas as pd
data = {
"city": ["London", "Paris", "Berlin"],
"temp": [15, 18, 12],
}
# 🎯 YOUR TURN: build the DataFrame and give the rows
# the custom labels "A", "B", "C" using the index= argument
df = pd.DataFrame(data, index=___) # replace ___ with a list of 3 labels
print(df)
# Expected output:
# city temp
# A London 15
# B Paris 18
# C Berlin 12📋 Quick Reference
| Input | Constructor |
|---|---|
| Dict of lists | pd.DataFrame({...}) |
| List of dicts | pd.DataFrame([{...}, ...]) |
| List of lists | pd.DataFrame(rows, columns=[...]) |
| NumPy array | pd.DataFrame(arr, columns=[...]) |
| Custom row labels | pd.DataFrame(data, index=[...]) |
🎯 Mini Challenge: Survey Records
Imagine survey responses arriving one record at a time as dictionaries:
- Make a list of 3 dictionaries, each with keys name and score
- Turn the list into a DataFrame
- Print it and its shape
import pandas as pd
records = [
{"name": "Ana", "score": 8},
{"name": "Ben", "score": 6},
{"name": "Cara", "score": 9},
]
df = pd.DataFrame(records)
print(df)
print("Shape:", df.shape)
# Output:
# name score
# 0 Ana 8
# 1 Ben 6
# 2 Cara 9
# Shape: (3, 2)
# ✅ Expected output:
# name score
# 0 Ana 8
# 1 Ben 6
# 2 Cara 9
# Shape: (3, 2)❓ Frequently Asked Questions
Lesson complete — you can build any DataFrame!
You've created DataFrames from dicts of lists, lists of dicts, lists of lists with named columns, and NumPy arrays — and you can set a custom index too.
Practice quiz
What constructor builds every kind of DataFrame in this lesson?
- pd.make_frame(...)
- pd.create(...)
- pd.DataFrame(...)
- pd.table(...)
Answer: pd.DataFrame(...). All four approaches use the same pd.DataFrame(...) constructor.
In a dict of lists like {'name':[...], 'age':[...]}, what does each key become?
- A column
- A row
- An index label
- A data type
Answer: A column. A dict of lists is column-oriented: each key is a column and its list holds that column's values.
In a list of dicts, what does each dictionary become?
- A column
- The index
- A dtype
- One row, with keys as column names
Answer: One row, with keys as column names. A list of dicts is row-oriented: each dict is one row and its keys become columns.
When is a list of dicts the most natural input?
- When you already have whole columns ready
- When records arrive row by row, like from an API or database
- When the data is a NumPy array
- Never
Answer: When records arrive row by row, like from an API or database. Row-by-row records map cleanly onto a list of dicts; missing keys become NaN.
If you pass a list of lists without columns=, what are the column labels?
- Integers 0, 1, 2, ...
- The first row's values
- Letters A, B, C
- An error
Answer: Integers 0, 1, 2, .... Without columns=, pandas labels the columns 0, 1, 2, ... — almost never what you want.
How do you give a NumPy-array-backed DataFrame meaningful column names?
- It happens automatically
- Use df.rename only
- Pass columns=[...] to the constructor
- You cannot
Answer: Pass columns=[...] to the constructor. Pass columns= (and optionally index=) so the otherwise unnamed columns get labels.
Which argument sets custom row labels instead of the default 0,1,2...?
- columns=
- index=
- labels=
- rows=
Answer: index=. index= sets the row labels; you can also promote a column with set_index.
Do a dict-of-lists and an equivalent list-of-dicts produce the same table?
- No, they always differ
- Only for numeric data
- Only with index= set
- Yes, the resulting DataFrames are identical
Answer: Yes, the resulting DataFrames are identical. Both inputs build the same DataFrame; .equals() confirms they are identical.
What does pd.DataFrame(records).shape return for 3 records of 2 keys each?
- (2, 3)
- (3, 2)
- (3, 3)
- (2, 2)
Answer: (3, 2). shape is (rows, columns): 3 rows and 2 columns gives (3, 2).
How do you promote an existing column to be the index?
- df.index('column')
- df.reindex()
- df.set_index('column')
- df.columns = 'column'
Answer: df.set_index('column'). df.set_index('column') makes that column the row index.
Continue this course
- Previous: The DataFrame: Rows and Columns
- Next: Reading & Writing Data (CSV, Excel, JSON) — Load and save data with read_csv, read_excel, read_json and to_* methods
- Quick reference: Pandas cheat sheet › Creating & Loading
Frequently asked questions
What are the main ways to create a Pandas DataFrame?
The four most common are: from a dictionary of lists (columns), from a list of dictionaries (rows), from a list of lists with an explicit columns= argument, and from a NumPy array. All use the same pd.DataFrame(...) constructor.
When should I use a dict of lists vs a list of dicts?
Use a dict of lists when your data is naturally column-oriented (you have whole columns ready). Use a list of dicts when your data comes row by row — for example records from an API or database, where each record is one dictionary.
How do I set a custom index on a DataFrame?
Pass index= to the constructor, e.g. pd.DataFrame(data, index=['a','b','c']), or call df.set_index('column') to promote an existing column to the index.
Can I build a DataFrame from a NumPy array?
Yes. Pass the 2-D array as the first argument and supply columns= (and optionally index=) so the otherwise unnamed rows and columns get meaningful labels.