Python Pandas: How to Get Nth Row or Every Nth Row from DataFrame
Selecting specific rows or a regular pattern of rows from a Pandas DataFrame based on their integer position is a common data access pattern. You might need to retrieve a single Nth row, or sample your data by selecting every Kth row. Pandas provides efficient integer-location based indexers like iloc
and other methods to achieve this.
This guide explains how to get a specific Nth row and how to select every Nth row (with variations like starting at a specific row or using the modulo operator) from a Pandas DataFrame.
Understanding Positional Indexing
Pandas DataFrames have an index that labels the rows. By default, this is a RangeIndex
starting from 0 (0, 1, 2, ...). "Positional indexing" refers to selecting rows based on these integer positions, regardless of what the actual index labels might be (e.g., if you have a custom string index). DataFrame.iloc
is the primary tool for this.
Example DataFrame
import pandas as pd
data = {
'Student_ID': [f'S{1001+i}' for i in range(10)],
'Test_Score': [85, 92, 78, 95, 88, 72, 90, 81, 79, 93],
'Subject': ['Math', 'Science', 'Math', 'History', 'Science', 'Math', 'History', 'Science', 'Math', 'History']
}
df = pd.DataFrame(data)
print("Original DataFrame:")
print(df)
Output:
Original DataFrame:
Student_ID Test_Score Subject
0 S1001 85 Math
1 S1002 92 Science
2 S1003 78 Math
3 S1004 95 History
4 S1005 88 Science
5 S1006 72 Math
6 S1007 90 History
7 S1008 81 Science
8 S1009 79 Math
9 S1010 93 History
Get a SINGLE Nth Row
Remember that Pandas uses zero-based indexing, so the first row is at position 0, the second at position 1, and so on.
Using DataFrame.iloc[n]
(Returns a Series)
Accessing a single row by its integer position using df.iloc[n]
returns the row as a Pandas Series.
import pandas as pd
df = pd.DataFrame({
'Student_ID': [f'S{1001+i}' for i in range(10)],
'Test_Score': [85, 92, 78, 95, 88, 72, 90, 81, 79, 93],
'Subject': ['Math', 'Science', 'Math', 'History', 'Science', 'Math', 'History', 'Science', 'Math', 'History']
})
# Get the 3rd row (index 2) as a Series
third_row_series = df.iloc[2]
print("Third row (index 2) as a Series:")
print(third_row_series)
# Get the first row (index 0)
first_row_series = df.iloc[0]
print("First row (index 0) as a Series:")
print(first_row_series)
Output:
Third row (index 2) as a Series:
Student_ID S1003
Test_Score 78
Subject Math
Name: 2, dtype: object
First row (index 0) as a Series:
Student_ID S1001
Test_Score 85
Subject Math
Name: 0, dtype: object
Using DataFrame.iloc[[n]]
(Returns a DataFrame)
If you want the Nth row returned as a single-row DataFrame (preserving the column structure), pass the index as a list: df.iloc[[n]]
.
import pandas as pd
df = pd.DataFrame({
'Student_ID': [f'S{1001+i}' for i in range(10)],
'Test_Score': [85, 92, 78, 95, 88, 72, 90, 81, 79, 93],
'Subject': ['Math', 'Science', 'Math', 'History', 'Science', 'Math', 'History', 'Science', 'Math', 'History']
})
# Get the 3rd row (index 2) as a DataFrame
third_row_df = df.iloc[[2]] # Note the double square brackets
print("Third row (index 2) as a DataFrame:")
print(third_row_df)
Output:
Third row (index 2) as a DataFrame:
Student_ID Test_Score Subject
2 S1003 78 Math
Using DataFrame.take([n])
(Returns a DataFrame)
The DataFrame.take()
method can also be used to select rows by their integer positions. It expects a list-like of indices.
import pandas as pd
df = pd.DataFrame({
'Student_ID': [f'S{1001+i}' for i in range(10)],
'Test_Score': [85, 92, 78, 95, 88, 72, 90, 81, 79, 93],
'Subject': ['Math', 'Science', 'Math', 'History', 'Science', 'Math', 'History', 'Science', 'Math', 'History']
})
# Get the 4th row (index 3) as a DataFrame
fourth_row_take = df.take([3])
print("Fourth row (index 3) using .take():")
print(fourth_row_take)
Output:
Fourth row (index 3) using .take():
Student_ID Test_Score Subject
3 S1004 95 History
Get EVERY Nth Row
This is useful for sampling or selecting rows at regular intervals.
Using DataFrame.iloc[::N]
(Slicing)
Python's slicing syntax start:stop:step
can be used with iloc
. To get every Nth row starting from the beginning: df.iloc[::N]
.
import pandas as pd
df = pd.DataFrame({
'Student_ID': [f'S{1001+i}' for i in range(10)],
'Test_Score': [85, 92, 78, 95, 88, 72, 90, 81, 79, 93],
'Subject': ['Math', 'Science', 'Math', 'History', 'Science', 'Math', 'History', 'Science', 'Math', 'History']
})
# Get every 3rd row (0, 3, 6, 9...)
every_3rd_row = df.iloc[::3]
# The ", :" part to select all columns is often optional for row-only slicing
# every_3rd_row = df.iloc[::3, :] # Explicitly all columns
print("Every 3rd row using iloc slicing (df.iloc[::3]):")
print(every_3rd_row)
Output:
Every 3rd row using iloc slicing (df.iloc[::3]):
Student_ID Test_Score Subject
0 S1001 85 Math
3 S1004 95 History
6 S1007 90 History
9 S1010 93 History
Starting at a Specific Row X, then Every Nth (df.iloc[X::N]
)
To start selection from a specific row position X
and then take every Nth
row:
import pandas as pd
df = pd.DataFrame({
'Student_ID': [f'S{1001+i}' for i in range(10)],
'Test_Score': [85, 92, 78, 95, 88, 72, 90, 81, 79, 93],
'Subject': ['Math', 'Science', 'Math', 'History', 'Science', 'Math', 'History', 'Science', 'Math', 'History']
})
# Get every 3rd row, starting from the 2nd row (index 1)
every_3rd_from_row1 = df.iloc[1::3]
print("Every 3rd row, starting from index 1 (df.iloc[1::3]):")
print(every_3rd_from_row1)
Output:
Every 3rd row, starting from index 1 (df.iloc[1::3]):
Student_ID Test_Score Subject
1 S1002 92 Science
4 S1005 88 Science
7 S1008 81 Science
Using the Modulo Operator (%
) on the Index
This method works well if your DataFrame has a default RangeIndex
(0, 1, 2, ...) or a numeric index where modulo makes sense.
import pandas as pd
df = pd.DataFrame({
'Student_ID': [f'S{1001+i}' for i in range(10)],
'Test_Score': [85, 92, 78, 95, 88, 72, 90, 81, 79, 93],
'Subject': ['Math', 'Science', 'Math', 'History', 'Science', 'Math', 'History', 'Science', 'Math', 'History']
})
# Get every 2nd row (rows where index % 2 == 0: 0, 2, 4, ...)
every_2nd_row_modulo = df[df.index % 2 == 0]
print("Every 2nd row using modulo operator (df.index % 2 == 0):")
print(every_2nd_row_modulo)
print()
# To get every 2nd row *starting from the second row* (indices 1, 3, 5...)
# (rows where index % 2 == 1)
every_2nd_row_odd_indices = df[df.index % 2 != 0] # Or == 1
print("Rows at odd indices using modulo (df.index % 2 != 0):")
print(every_2nd_row_odd_indices)
Output:
Every 2nd row using modulo operator (df.index % 2 == 0):
Student_ID Test_Score Subject
0 S1001 85 Math
2 S1003 78 Math
4 S1005 88 Science
6 S1007 90 History
8 S1009 79 Math
Rows at odd indices using modulo (df.index % 2 != 0):
Student_ID Test_Score Subject
1 S1002 92 Science
3 S1004 95 History
5 S1006 72 Math
7 S1008 81 Science
9 S1010 93 History
- If your DataFrame has a non-numeric index or an index that doesn't start at 0 in a predictable way, you might need to
reset_index()
first to use this method reliably based on row position:df[df.reset_index().index % N == K]
(whereK
is the remainder for the desired starting offset).
Exclude Every Nth Row
To get all rows except every Nth row, you can invert the condition used with the modulo operator.
import pandas as pd
df = pd.DataFrame({
'Student_ID': [f'S{1001+i}' for i in range(10)],
'Test_Score': [85, 92, 78, 95, 88, 72, 90, 81, 79, 93],
'Subject': ['Math', 'Science', 'Math', 'History', 'Science', 'Math', 'History', 'Science', 'Math', 'History']
})
# Exclude every 3rd row (i.e., keep rows where index % 3 is NOT 0)
# This keeps rows with index 1, 2, 4, 5, 7, 8...
exclude_every_3rd_row = df[df.index % 3 != 0]
print("Excluding every 3rd row (keeping rows where index % 3 != 0):")
print(exclude_every_3rd_row)
Output:
Excluding every 3rd row (keeping rows where index % 3 != 0):
Student_ID Test_Score Subject
1 S1002 92 Science
2 S1003 78 Math
4 S1005 88 Science
5 S1006 72 Math
7 S1008 81 Science
8 S1009 79 Math
Conclusion
Pandas offers flexible ways to select rows by their integer positions:
- To get a single Nth row:
df.iloc[n]
(returns a Series).df.iloc[[n]]
(returns a DataFrame).df.take([n])
(returns a DataFrame).
- To get every Nth row:
df.iloc[start::step]
(slicing) is very powerful and concise.df[df.index % N == K]
(modulo operator) works well for DataFrames with a default or predictable numeric index.
Choose the method that best fits your specific selection criteria (single row, patterned selection, desired output type) and the nature of your DataFrame's index. iloc
is generally the most versatile tool for positional indexing.