Written and maintained by CASRAI Editorial Board
Last updated
To create a DataFrame in Python, call pandas.DataFrame() on a dict, a list of dicts or a NumPy array: pd.DataFrame(data=d) with d = {"col1": [1, 2], "col2": [3, 4]} returns a two-column table with a default 0, 1 row index. What differs between input types is what pandas does with labels and with data that does not line up, and that is what this guide documents, following the pandas 3.1.0 documentation.
What it is used for in research
A pandas DataFrame is the labelled, table-shaped structure that most Python analysis code works on: columns have names, rows have an index, and columns can hold different types. Researchers typically meet it at two points: reading a file into one (see the exploratory data analysis walkthrough) and building a small one by hand to test a calculation or to hold results. This guide covers the second case, building from objects already in memory.
Install or access
The pandas installation page lists these commands:
pip install pandas
conda install -c conda-forge pandas
pandas is distributed through PyPI, conda-forge and GitHub. The installation page notes that pandas from Anaconda is not officially managed by the pandas development team. Import it as import pandas as pd and, for the array examples below, import numpy as np.
Step-by-step: create a DataFrame
The constructor signature in the API reference is pandas.DataFrame(data=None, index=None, columns=None, dtype=None, copy=None). The steps below use examples from the official reference and user guide.
- From a dict of lists. Keys become column names; column order follows insertion order.
d = {"col1": [1, 2], "col2": [3, 4]} df = pd.DataFrame(data=d)All lists must share the same length. If you pass
index, it must be the same length too; if you do not, the index isrange(n), where n is the list length. For example,index=["a", "b", "c", "d"]labels the rows of a four-element dict of lists. - From a list of dicts. Each dict is a row. The columns are the union of the keys, and a key missing from a row is filled with NaN.
data2 = [{"a": 1, "b": 2}, {"a": 5, "b": 10, "c": 20}] pd.DataFrame(data2)Column
ccomes back as NaN for the first row and 20.0 for the second. Addindex=["first", "second"]to label rows, orcolumns=["a", "b"]to dropc. - From a NumPy array, naming the columns.
pd.DataFrame(np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]]), columns=["a", "b", "c"])This gives rows
1 2 3,4 5 6and7 8 9under columns a, b and c. - From a dict, with keys as row labels.
DataFrame.from_dictworks like the constructor except fororient, which is"columns"by default and can be set to"index"so the dict keys become row labels.pd.DataFrame.from_dict(dict([("A", [1, 2, 3]), ("B", [4, 5, 6])]), orient="index", columns=["one", "two", "three"])Row A is
1 2 3and row B is4 5 6. - From a dict of Series. The Series are aligned on their indexes (see the next section for what that does to your data).
d = {"one": pd.Series([1.0, 2.0, 3.0], index=["a", "b", "c"]), "two": pd.Series([1.0, 2.0, 3.0, 4.0], index=["a", "b", "c", "d"])} pd.DataFrame(d)
The data argument also accepts an Iterable or another DataFrame, and a dict may contain Series, arrays, constants, dataclass or list-like objects. A list of dataclass instances works too: with Point = make_dataclass("Point", [("x", int), ("y", int)]), the call pd.DataFrame([Point(0, 0), Point(0, 3), Point(2, 3)]) returns columns x and y with rows 0 0, 0 3 and 2 3.
Output and how to read it
Three things are worth checking on any new DataFrame: the index, the dtypes and any missing values.
- Index. With no index information in the input and none passed, pandas uses a RangeIndex (0, 1, 2, …).
- dtypes. For the dict of lists above,
df.dtypesreportsint64for both columns. Passingdtype=np.int8reportsint8for both. Only a single dtype is allowed in the constructor; if it is None, pandas infers types. - Missing data. pandas uses
np.nanto represent missing values. In the reference example{"col1": [0, 1, 2, 3], "col2": pd.Series([2, 3], index=[2, 3])}built withindex=[0, 1, 2, 3],col2reads NaN, NaN, 2.0, 3.0: the integers became floats because NaN needs a float column. Withdtype=str, a missing value stays missing rather than turning into the string “nan”.
Once the frame looks right, the usual next jobs are renaming columns, dropping columns, handling missing values (see NumPy NaN) and the wider data cleaning steps.
What the constructor does with mismatched input
The user guide is explicit that passed labels override the data. This table lists each rule with its source example.
| Input | Rule | Documented example result |
|---|---|---|
| Dict of lists or arrays | All must share the same length; a passed index must match that length; no index gives range(n) | {"one": [1.0, 2.0, 3.0, 4.0], "two": [4.0, 3.0, 2.0, 1.0]} with index=["a", "b", "c", "d"] |
| Dict of Series | The index is the union of the Series indexes; with no columns passed, columns are the dict keys in order | Series of length 3 and 4 give a row d with one NaN and two 4.0 |
Dict of Series plus index |
The passed index is guaranteed; data not matching it is discarded | index=["d", "b", "a"] reorders the rows to d, b, a |
Dict plus columns |
Passed columns override the dict keys; names with no matching key are all NaN | columns=["two", "three"] gives three all NaN |
| List of dicts | Columns are the union of the keys; absent keys become NaN; columns selects |
Keys a, b, c: c is NaN, 20.0; columns=["a", "b"] drops c |
| Data that already has column labels | columns performs column selection instead of naming |
Structured array with fields a, b, c and columns=["c", "a"] gives columns c, a with rows 3 1, 6 4, 9 7 |
| Dict data | copy=None behaves like copy=True |
Not applicable |
| DataFrame or 2D ndarray data | copy=None behaves like copy=False |
Not applicable |
Troubleshooting
Lists of different lengths in a dict
The documented rule is that all arrays and lists must share the same length, and a passed index must match it. Pad the shorter list, or wrap each in a pd.Series so pandas aligns them and fills the gaps with NaN.
Unexpected NaN after passing an index or columns
Passing index or columns guarantees those labels in the result. A label with no matching data comes back as NaN, and data with no matching label is discarded. If the result has empty columns or fewer rows than you supplied, compare your labels with the keys or Series indexes of the input.
Column names ignored when passing a structured array or DataFrame
When the data already carries column labels, columns= selects from them rather than renaming them. To rename, use the approach in the rename columns guide.
Integers turning into floats
In the reference example the NaN-containing column reads 2.0 and 3.0, not 2 and 3. Check df.dtypes after any construction that involves alignment.
Changing the original data after building the frame
For dict input the default behaves like copy=True, so the DataFrame holds its own copy. For a 2D ndarray the default behaves like copy=False, so check the reference before assuming the array and frame are independent.
Free alternatives
pandas itself offers other free ways to create a DataFrame from data you already hold or from files.
| Method | What it takes | Source note |
|---|---|---|
pd.DataFrame(...) |
ndarray, Iterable, dict or DataFrame | API reference |
DataFrame.from_dict |
A dict of dicts or a dict of array-like sequences; orient="index" makes dict keys the row labels |
User guide, data structures |
DataFrame.from_records |
A list of tuples or an ndarray with a structured dtype; the index may be a specific field of the structured dtype | User guide, data structures |
read_csv |
A CSV or other flat text file; the workhorse function for reading text files | User guide, IO tools |
read_excel |
An MS Excel file | User guide, IO tools |
read_json |
A JSON file | User guide, IO tools |
For a worked example of reading data and exploring it, see data analysis in Python.
FAQ
How do I create a DataFrame from a list of dicts?
Pass the list straight to pd.DataFrame(). Each dict becomes a row, columns are the union of all keys, and keys missing from a dict become NaN. Use columns=[...] to keep only some keys.
How do I create a DataFrame from a NumPy array?
Call pd.DataFrame(arr, columns=["a", "b", "c"]).
How do I create an empty DataFrame?
pd.DataFrame() is valid because data defaults to None.
How do I create a DataFrame from a CSV file?
Use pd.read_csv("file.csv"), which the pandas documentation calls the workhorse function for reading text files. See the exploratory data analysis guide for what to do next.
Sources
- pandas, pandas.DataFrame API reference, documentation version 3.1.0, checked 2026-10-29.
- pandas, Intro to data structures, checked 2026-10-29.
- pandas, Installation, checked 2026-10-29.
- pandas, IO tools (text, CSV, HDF5, …), checked 2026-10-29.







