Skip to main content

Python Pandas: How to Convert Pandas DataFrame Columns to a Series

When working with pandas, each column in a DataFrame is already a Series under the hood. However, there are situations where you need to explicitly extract a column as a standalone Series - for example, when passing data to functions that expect a Series, performing Series-specific operations, or separating data for analysis.

In this guide, you'll learn multiple ways to convert DataFrame columns to Series objects, understand what happens during the conversion, and see practical use cases.

Understanding the Relationship

A pandas DataFrame is essentially a collection of Series objects that share a common index. When you select a single column from a DataFrame, pandas automatically returns it as a Series:

import pandas as pd

df = pd.DataFrame({
'Name': ['Alice', 'Bob', 'Charlie'],
'Age': [25, 30, 35],
'Score': [88.5, 92.3, 76.8]
})

# Selecting a single column returns a Series
column = df['Name']

print(column)
print(f"\nType: {type(column)}")

Output:

0      Alice
1 Bob
2 Charlie
Name: Name, dtype: object

Type: <class 'pandas.core.series.Series'>

The result is already a Series - no explicit conversion is needed for single-column selection.

Method 1: Using Bracket Notation (df['column'])

The most common and recommended way to extract a column as a Series:

import pandas as pd

df = pd.DataFrame({
'August': [10, 25, 34, 4.85, 71.2],
'September': [4.8, 54, 68, 9.25, 58],
'October': [78, 5.8, 8.52, 12, 1.6],
'November': [100, 5.8, 50, 8.9, 77]
})

# Extract a column as Series
august_series = df['August']

print(august_series)
print(f"\nType: {type(august_series)}")

Output:

0    10.00
1 25.00
2 34.00
3 4.85
4 71.20
Name: August, dtype: float64

Type: <class 'pandas.core.series.Series'>

Method 2: Using Dot Notation (df.column)

For column names that are valid Python identifiers (no spaces, no special characters, don't start with a number):

import pandas as pd

df = pd.DataFrame({
'August': [10, 25, 34, 4.85, 71.2],
'September': [4.8, 54, 68, 9.25, 58]
})

# Dot notation
september_series = df.September

print(september_series)
print(f"\nType: {type(september_series)}")

Output:

0     4.80
1 54.00
2 68.00
3 9.25
4 58.00
Name: September, dtype: float64

Type: <class 'pandas.core.series.Series'>
When Dot Notation Fails

Dot notation doesn't work for column names that:

  • Contain spaces: df.my column → SyntaxError
  • Conflict with DataFrame methods: df.count returns the method, not the column
  • Start with numbers: df.2024_sales → SyntaxError

Always use bracket notation (df['column name']) for reliability:

# ❌ These won't work with dot notation
# df.my column
# df.2024_sales

# ✅ Bracket notation works for any column name
df['my column']
df['2024_sales']

Method 3: Using .iloc[] for Position-Based Selection

Select columns by their integer position using .iloc[]:

import pandas as pd

df = pd.DataFrame({
'August': [10, 25, 34],
'September': [4.8, 54, 68],
'October': [78, 5.8, 8.52],
'November': [100, 5.8, 50]
})

# First column (index 0)
first_col = df.iloc[:, 0]
print("First column:")
print(first_col)
print(f"Type: {type(first_col)}\n")

# Last column (index -1)
last_col = df.iloc[:, -1]
print("Last column:")
print(last_col)
print(f"Type: {type(last_col)}")

Output:

First column:
0 10
1 25
2 34
Name: August, dtype: int64
Type: <class 'pandas.core.series.Series'>

Last column:
0 100.0
1 5.8
2 50.0
Name: November, dtype: float64
Type: <class 'pandas.core.series.Series'>

Method 4: Using .loc[] for Label-Based Selection

Select columns by their name using .loc[]:

import pandas as pd

df = pd.DataFrame({
'August': [10, 25, 34],
'September': [4.8, 54, 68],
'October': [78, 5.8, 8.52]
})

# Select by column name
october = df.loc[:, 'October']

print(october)
print(f"\nType: {type(october)}")

Output:

0    78.00
1 5.80
2 8.52
Name: October, dtype: float64

Type: <class 'pandas.core.series.Series'>

Method 5: Using squeeze() for Single-Column DataFrames

When you have a DataFrame with a single column and want to convert it to a Series, use squeeze():

import pandas as pd

df = pd.DataFrame({'Score': [88, 92, 76, 95, 84]})

print(f"Before squeeze - Type: {type(df)}")
print(df)

# Squeeze single-column DataFrame into a Series
series = df.squeeze()

print(f"\nAfter squeeze - Type: {type(series)}")
print(series)

Output:

Before squeeze - Type: <class 'pandas.core.frame.DataFrame'>
Score
0 88
1 92
2 76
3 95
4 84

After squeeze - Type: <class 'pandas.core.series.Series'>
0 88
1 92
2 76
3 95
4 84
Name: Score, dtype: int64
note

squeeze() only converts to a Series if the DataFrame has exactly one column. If the DataFrame has multiple columns, it returns the DataFrame unchanged.

Converting Multiple Columns to Separate Series

To extract multiple columns as individual Series objects:

import pandas as pd

df = pd.DataFrame({
'Name': ['Alice', 'Bob', 'Charlie'],
'Age': [25, 30, 35],
'Score': [88.5, 92.3, 76.8]
})

# Extract multiple columns as separate Series
name_series = df['Name']
age_series = df['Age']
score_series = df['Score']

print(f"Name Series: {name_series.tolist()}")
print(f"Age Series: {age_series.tolist()}")
print(f"Score Series: {score_series.tolist()}")

# All are Series
for s in [name_series, age_series, score_series]:
print(f" {s.name}: {type(s).__name__}")

Output:

Name Series:  ['Alice', 'Bob', 'Charlie']
Age Series: [25, 30, 35]
Score Series: [88.5, 92.3, 76.8]
Name: Series
Age: Series
Score: Series

Practical Example: Series Operations After Extraction

A common reason to extract columns as Series is to perform Series-specific analysis:

import pandas as pd

df = pd.DataFrame({
'Month': ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun'],
'Revenue': [15000, 18000, 22000, 19500, 25000, 21000],
'Expenses': [12000, 14000, 16000, 15000, 18000, 17000]
})

# Extract as Series
revenue = df['Revenue']
expenses = df['Expenses']

# Series operations
profit = revenue - expenses
growth_rate = revenue.pct_change() * 100

print("Revenue Analysis:")
print(f" Total: ${revenue.sum():,}")
print(f" Average: ${revenue.mean():,.0f}")
print(f" Best: {df.loc[revenue.idxmax(), 'Month']} (${revenue.max():,})")
print(f"\nProfit per month: {profit.tolist()}")
print(f"Growth rates: {[f'{x:.1f}%' if not pd.isna(x) else 'N/A' for x in growth_rate]}")

Output:

Revenue Analysis:
Total: $120,500
Average: $20,083
Best: May ($25,000)

Profit per month: [3000, 4000, 6000, 4500, 7000, 4000]
Growth rates: ['N/A', '20.0%', '22.2%', '-11.4%', '28.2%', '-16.0%']

Verifying the Conversion

To confirm that a column has been correctly extracted as a Series:

import pandas as pd

df = pd.DataFrame({'A': [1, 2, 3], 'B': [4, 5, 6]})

column = df['A']

print(f"Type: {type(column)}")
print(f"Name: {column.name}")
print(f"Dtype: {column.dtype}")
print(f"Shape: {column.shape}")
print(f"Is Series: {isinstance(column, pd.Series)}")

Output:

Type:    <class 'pandas.core.series.Series'>
Name: A
Dtype: int64
Shape: (3,)
Is Series: True

Quick Comparison of Methods

MethodSyntaxSelection TypeBest For
Bracket notationdf['column']By name✅ Most reliable, any column name
Dot notationdf.columnBy nameQuick access, simple names only
.iloc[:, n]df.iloc[:, 0]By positionWhen you know the column index
.loc[:, 'col']df.loc[:, 'col']By nameExplicit label-based selection
.squeeze()df.squeeze()Single columnConverting single-column DataFrames

Conclusion

Converting pandas DataFrame columns to Series is straightforward because each column is inherently a Series:

  • Bracket notation (df['column']) is the most reliable and recommended method - it works with any column name and is universally understood.
  • Dot notation (df.column) is convenient for quick access but fails with special characters or names that conflict with DataFrame methods.
  • .iloc[:, n] is useful when you need to select columns by their position rather than name.
  • .squeeze() is specialized for converting single-column DataFrames into Series.

In most cases, simply selecting a column with df['column_name'] is all you need - pandas automatically returns a Series object ready for analysis.