Data AnalyticsPandas & NumPybeginner
Updated:

Pandas DataFrame and Series Explained

4 min read

The Series and DataFrame are the two objects the whole pandas library is built on. Learn how they relate, how to create them, and how to move between them.

TL;DR – Quick Answer

A pandas Series is a single labelled column of values with an index. A DataFrame is a two-dimensional table made of several Series that share the same row index. You create a DataFrame from a dictionary of columns, select one column to get a Series back, and both structures carry an index that aligns data during every operation. Understanding this relationship is the foundation of all pandas work.

On This Page

Every single thing you do in pandas happens inside one of two objects: the Series and the DataFrame. Get a clear mental model of what each one is and how they relate, and the rest of the library stops feeling like a pile of unrelated methods. This tutorial builds that model with small, runnable examples you can type yourself.

The short version: a Series is one column, a DataFrame is a whole table, and a DataFrame is literally a bundle of Series sharing the same row labels. Once that clicks, selecting data, computing statistics and reshaping tables all follow naturally.

The Series: one labelled column

A Series is a one-dimensional array of values, each paired with a label called the index. Think of it as a single column lifted out of a spreadsheet, but with its own row labels attached. You create one from a list:

import pandas as pd

ages = pd.Series([24, 31, 28, 45, 22], name="age")
print(ages)
0    24
1    31
2    28
3    45
4    22
Name: age, dtype: int64

The left column is the index (0 to 4 here, assigned automatically), the right column is the values, and dtype: int64 tells you these are whole numbers. A Series knows how to compute on itself:

print(ages.mean())
print(ages.max())
30.0
45

You can also give a Series meaningful labels instead of the default integers, which is where its power over a plain list shows:

scores = pd.Series([88, 72, 95], index=["Aarti", "Bhaskar", "Chitra"])
print(scores["Bhaskar"])
72

Now the index acts like a lookup key. This label-based alignment is the single feature that makes pandas different from raw NumPy arrays.

The DataFrame: many Series, one index

A DataFrame is a two-dimensional table: rows and columns, where every column is a Series and all columns share the same index. The most common way to build one is from a dictionary where each key becomes a column. This is small illustrative sample data:

import pandas as pd

data = {
    "name": ["Aarti", "Bhaskar", "Chitra", "Devan"],
    "city": ["Hyderabad", "Hyderabad", "Bengaluru", "Pune"],
    "age": [24, 31, 28, 45],
    "salary": [48000, 65000, 52000, 90000],
}
df = pd.DataFrame(data)
print(df)
      name       city  age  salary
0    Aarti  Hyderabad   24   48000
1  Bhaskar  Hyderabad   31   65000
2   Chitra  Bengaluru   28   52000
3    Devan       Pune   45   90000

The four columns are four Series, all glued together by the shared index 0 to 3. You can confirm the relationship by pulling one column out:

print(type(df["salary"]))
<class 'pandas.core.series.Series'>

A single column really is a Series. That is why every Series method you learned above works on any column of any DataFrame.

Moving between the two

Selecting columns is where the Series/DataFrame distinction bites beginners, so make it explicit. Single brackets give a Series; double brackets give a DataFrame:

print(df["age"].mean())          # Series -> a number
print(df[["name", "salary"]])    # list of columns -> DataFrame
32.0
      name  salary
0    Aarti   48000
1  Bhaskar   65000
2   Chitra   52000
3    Devan   90000

The rule to remember: pass a string to get one column as a Series; pass a list of strings to get a DataFrame, even if that list has one item. Some methods only exist on one type, so knowing which you are holding saves confusion.

The index ties everything together

Every Series and DataFrame carries an index, and pandas uses it to align data automatically during operations. By default you get a RangeIndex (0, 1, 2, …), but you can promote a meaningful column to be the index:

df2 = df.set_index("name")
print(df2.loc["Chitra"])
city      Bengaluru
age              28
salary        52000
Name: Chitra, dtype: object

With name as the index you can look up a whole row by label. Notice the returned row is itself a Series, with the former column names now acting as its index. This symmetry, columns of a row and rows of a column both being Series, is the elegant core of pandas.

Practical usage

In real analysis you rarely build DataFrames by hand; you read them from files. But you constantly reach into them for single Series to compute a statistic, apply a transformation, or feed a chart. A typical workflow looks like: load a DataFrame, select the column you care about as a Series, compute or clean it, then assign the result back as a new column. Understanding that a column is a Series makes every one of those steps intuitive rather than magical.

Common mistakes

  • Using single brackets when you need a DataFrame. df["col"] is a Series; some downstream code expects a DataFrame and breaks. Use df[["col"]] when a table is required.
  • Assuming positional access works everywhere. After set_index, df.loc["Chitra"] uses the label, not a position. Mixing label and position access is a frequent source of confusion, which the loc and iloc tutorial resolves.
  • Ignoring index alignment. When you add two Series with different indexes, pandas aligns by label and fills mismatches with NaN. This surprises beginners who expect element-by-element math like plain lists.
  • Rebuilding an index accidentally. Operations like reset_index() change row labels; if later code relies on the old labels it will fail silently.

In interviews

Expect the direct question "what is the difference between a Series and a DataFrame?" Answer crisply: a Series is one-dimensional labelled data, a DataFrame is a two-dimensional table whose columns are Series sharing an index. Interviewers may follow up on how selecting a column returns a Series, or ask what the index is for, so mention automatic label alignment. Being fluent about these structures signals that you understand pandas from the ground up rather than just memorizing recipes.

Where this fits in your learning path

This tutorial sits right after the pandas introduction in the data analytics path. With the Series and DataFrame clear in your head, the natural next step is precise row and column selection in pandas loc and iloc. If you want to understand the array machinery underneath, the NumPy introduction shows the foundation pandas is built on. These structures are the bedrock of the data analyst toolkit.

Frequently Asked Questions

What is the difference between a pandas Series and DataFrame?
A Series is one-dimensional: a single column of values with an index. A DataFrame is two-dimensional: a table of rows and columns where each column is itself a Series. Selecting one column from a DataFrame returns a Series, and combining several Series with a shared index gives you a DataFrame.
How do I create a DataFrame in pandas?
The most common way is pd.DataFrame(dict) where each dictionary key is a column name and each value is a list of column values. You can also build one from a list of dictionaries, a NumPy array, or by reading a file. All approaches produce the same row-and-column structure.
What is the index in a pandas DataFrame?
The index is the set of row labels. By default pandas assigns a RangeIndex of 0, 1, 2 and so on, but you can set a meaningful column such as an ID as the index with set_index. The index is what pandas uses to align data when you combine or compute across objects.
How do I get a single column from a DataFrame?
Use df['column_name'] to get that column back as a Series, or df[['column_name']] with double brackets to get a one-column DataFrame. The single-bracket form is more common when you want to compute on the values. Choose based on whether you need a Series or a DataFrame result.
Can a DataFrame column hold different data types?
Each individual column holds one data type, but different columns can hold different types. One column can be integers, another text, another dates. Pandas tracks the type of every column separately in the dtypes attribute.

Want to Build Your Career in Data Analytics with AI?

Join CodeBegun and train with working industry engineers — View the Data Analytics curriculum

Apply for Demo Class →
Siva Prasad Galaba
Founder, CodeBegun · Staff Engineer

Founder of CodeBegun. 15+ years building Java systems at companies like Crunchyroll. Teaches Java, Spring Boot and system design the way the industry actually works, and mentors students through projects, mock interviews and placement preparation.

Technically reviewed by CodeBegun Technical TeamLast reviewed 16 July 2026 LinkedIn
Chat with us