Skip to content

Python Pandas: How to Select the Last Row in Pandas

Learn efficient methods to select the last row in a Pandas DataFrame using iloc[-1], tail(1), or iat for performance-critical operations, with edge-case handling.

Finding the last entry in a dataset is a common requirement-whether you're checking the latest timestamp, the most recent transaction, or simply the final record. Pandas offers several approaches, each suited to different needs.

Using iloc: the Standard Way

Python's negative indexing makes selecting the last row intuitive with iloc[-1]:

import pandas as pd

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

last_row = df.iloc[-1]
print(last_row)

Output:

Name    Charlie
Age          35
Name: 2, dtype: object

Accessing Values from the Result

import pandas as pd

df = pd.DataFrame({
    'Name': ['Alice', 'Bob', 'Charlie'],
    'Age': [25, 30, 35],
    'City': ['NYC', 'LA', 'Chicago']
})

last_row = df.iloc[-1]

print(last_row['Name'])    # Charlie
print(last_row['Age'])     # 35

print(last_row.iloc[0])    # Charlie

Using tail(): Keep DataFrame Structure

When you need to preserve the DataFrame format (headers, structure, ability to chain operations), use tail(1):

import pandas as pd

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

last_row_df = df.tail(1)
print(last_row_df)

Output:

      Name  Age
2  Charlie   35

When to Use tail()

import pandas as pd

df = pd.DataFrame({
    'Name': ['Alice', 'Bob', 'Charlie'],
    'Score': [85, 92, 78]
})

result = df.tail(1).to_dict('records')[0]
print(result)  

first_and_last = pd.concat([df.head(1), df.tail(1)])
print(first_and_last)

Output:

{'Name': 'Charlie', 'Score': 78}
      Name  Score
0    Alice     85
2  Charlie     78

Using iat: Maximum Performance

For extracting a single cell value, iat provides the fastest access:

import pandas as pd

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

last_name = df.iat[-1, 0]
print(last_name)  # Charlie

last_age = df.iat[-1, 1]
print(last_age)   # 35

Output:

Charlie
35

Performance Comparison

import pandas as pd
import timeit

df = pd.DataFrame({'A': range(100000), 'B': range(100000)})

iloc_time = timeit.timeit(lambda: df.iloc[-1, 0], number=10000)
iat_time = timeit.timeit(lambda: df.iat[-1, 0], number=10000)

print(f"iloc: {iloc_time:.4f}s")
print(f"iat:  {iat_time:.4f}s")
print(f"iat is {iloc_time/iat_time:.1f}x faster")

Output:

iloc: 0.2265s
iat:  0.1475s
iat is 1.5x faster

Edge Cases

Empty DataFrame

import pandas as pd

df = pd.DataFrame(columns=['Name', 'Age'])

try:
    last_row = df.iloc[-1]
except IndexError:
    print("DataFrame is empty!")

last_row_df = df.tail(1)
print(f"Empty check: {last_row_df.empty}")  # True

if not df.empty:
    last_row = df.iloc[-1]
else:
    last_row = None

Output:

DataFrame is empty!
Empty check: True

Single Row DataFrame

import pandas as pd

df = pd.DataFrame({'Name': ['Alice'], 'Age': [25]})

print(df.iloc[-1]['Name'])   # Alice
print(df.tail(1))            # DataFrame with one row
print(df.iat[-1, 0])         # Alice

Output:

Alice
    Name  Age
0  Alice   25
Alice

Getting Multiple Last Rows

For more than just the last row:

import pandas as pd

df = pd.DataFrame({
    'Date': pd.date_range('2024-01-01', periods=10),
    'Value': range(10)
})

print(df.tail(3))

print(df.iloc[-3:])

print(df.iloc[-6::2])

Output:

        Date  Value
7 2024-01-08      7
8 2024-01-09      8
9 2024-01-10      9
        Date  Value
7 2024-01-08      7
8 2024-01-09      8
9 2024-01-10      9
        Date  Value
4 2024-01-05      4
6 2024-01-07      6
8 2024-01-09      8

Practical Example: Time Series

import pandas as pd

df = pd.DataFrame({
    'Date': pd.date_range('2024-01-01', periods=5),
    'Price': [100, 102, 99, 105, 103],
    'Volume': [1000, 1200, 800, 1500, 1100]
})

latest = df.iloc[-1]
print(f"Latest price: ${latest['Price']} on {latest['Date'].date()}")

previous = df.iloc[-2]
change = latest['Price'] - previous['Price']
print(f"Change: ${change:+.2f}")

Output:

Latest price: $103 on 2024-01-05
Change: $-2.00

Quick Reference

Method Returns Best For
df.iloc[-1] Series General access to last row
df.tail(1) DataFrame Preserving structure, chaining
df.iat[-1, col] Scalar Single value, maximum speed
df.iloc[-n:] DataFrame Last n rows

Summary

  • Use df.iloc[-1] for standard last-row access-it returns a Series that's easy to work with.
  • Use df.tail(1) when you need to maintain DataFrame structure for further operations.
  • Use df.iat[-1, col] in performance-critical scenarios where you only need a single cell value.

Always check for empty DataFrames before accessing with iloc to avoid IndexError.

Navigation