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'>
Dot notation doesn't work for column names that:
- Contain spaces:
df.my column→ SyntaxError - Conflict with DataFrame methods:
df.countreturns 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
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
| Method | Syntax | Selection Type | Best For |
|---|---|---|---|
| Bracket notation | df['column'] | By name | ✅ Most reliable, any column name |
| Dot notation | df.column | By name | Quick access, simple names only |
.iloc[:, n] | df.iloc[:, 0] | By position | When you know the column index |
.loc[:, 'col'] | df.loc[:, 'col'] | By name | Explicit label-based selection |
.squeeze() | df.squeeze() | Single column | Converting 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.