Skip to main content
v2026.11,858 entries · CC-BY 4.0
LAC HealthMedical & Research SuppliesReagents, PPE & instruments — chain-of-custody documented.Fast, traceable sourcing built for regulated research environments, from bench consumables to instrumentation.Shop lac.us CodeCASRAIlac.us

Create a DataFrame in Python: pandas DataFrame() from Dicts, Lists and Arrays

How to create a pandas DataFrame from dicts, lists of dicts and arrays, with the documented rules for index, columns, dtype, copy and NaN alignment.

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.

  1. 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 is range(n), where n is the list length. For example, index=["a", "b", "c", "d"] labels the rows of a four-element dict of lists.

  2. 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 c comes back as NaN for the first row and 20.0 for the second. Add index=["first", "second"] to label rows, or columns=["a", "b"] to drop c.

  3. 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 6 and 7 8 9 under columns a, b and c.

  4. From a dict, with keys as row labels. DataFrame.from_dict works like the constructor except for orient, 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 3 and row B is 4 5 6.

  5. 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.dtypes reports int64 for both columns. Passing dtype=np.int8 reports int8 for both. Only a single dtype is allowed in the constructor; if it is None, pandas infers types.
  • Missing data. pandas uses np.nan to represent missing values. In the reference example {"col1": [0, 1, 2, 3], "col2": pd.Series([2, 3], index=[2, 3])} built with index=[0, 1, 2, 3], col2 reads NaN, NaN, 2.0, 3.0: the integers became floats because NaN needs a float column. With dtype=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

Follow CASRAI

Research-administration guidance, standards updates and independent tool reviews.

Ask CASRAI · free to try

Ask about Create a DataFrame in Python: pandas DataFrame() from Dicts, Lists and Arrays

Ask your first 2 questions free below. Subscribers get 150 a day for $29 a month.

An AI assistant specialized in research administration. It cites the sources behind every answer, labels web answers and says when it can't answer.

Answers draw on CASRAI's guides and dictionary plus the federal and funder documents we index: Federal Register, Grants.gov, Regulations.gov and UKRI.

Works on this site and inside Claude, Cursor and the AI tools you already use.

Everything CASRAI publishes — this page, the dictionary, the guides and the news — stays free to read, with no account and no card.

Referenced across the research world

University of Cambridge logoColumbia University logoCrossref logoUniversity of Edinburgh logoHarvard University logoUniversity of Oxford logoPrinceton University logoStanford School of Medicine logoUniversity College London logoORCID logoUniversity of Cambridge logoColumbia University logoCrossref logoUniversity of Edinburgh logoHarvard University logoUniversity of Oxford logoPrinceton University logoStanford School of Medicine logoUniversity College London logoORCID logo
  • University of Cambridge logo
  • Columbia University logo
  • Crossref logo
  • University of Edinburgh logo
  • Harvard University logo
  • University of Oxford logo
  • Princeton University logo
  • Stanford School of Medicine logo
  • University College London logo
  • ORCID logo

View CASRAI adoption →