Why pandas loc/iloc Slows Down Loops and How at/iat Can Speed It Up
This article explains how using pandas loc and iloc inside Python loops can be extremely slow, demonstrates the performance difference with concrete timing examples, and shows that replacing them with the scalar accessors at and iat can accelerate the operation by up to sixty times.
In pandas, loc and iloc are label‑ and position‑based indexers used to access values in a DataFrame. They work well for single‑element access but become very slow when used inside Python loops.
Basic usage of loc and iloc
Given a DataFrame df with a column a, the value in the second row can be accessed with: df.loc[1, 'a'] # output: 10 Similarly, the positional indexer iloc retrieves the same value:
df.iloc[1, 0] # output: 10Performance when combined with a loop
Adding a new column c as the sum of columns a and b using a for loop and loc takes about 2414 seconds (≈40 minutes):
import time
start = time.time()
for index, row in df.iterrows():
df.loc[index, 'c'] = row.a + row.b
end = time.time()
print(end - start) # 2414 secondsUsing at (or iat ) as a faster alternative
Replacing loc with the scalar accessor at reduces the execution time to roughly 40 seconds, about 60× faster:
import time
start = time.time()
for index, row in df.iterrows():
df.at[index, 'c'] = row.a + row.b
end = time.time()
print(end - start) # 40 secondsWhy at / iat are faster
atand iat are designed for scalar access – they retrieve or set a single element without the overhead of label handling or vectorized logic that loc / iloc provide. Consequently they consume less memory and execute more quickly for element‑wise operations.
Limitations of at / iat
These accessors cannot select multiple rows or columns. Attempting to use them with a slice raises an error:
# This raises an error
df.at[:3, 'a'] # ValueError: integer‑based indexing can only use integer scalarsIn contrast, loc and iloc support slicing and vectorized operations, which is why they remain useful for bulk data manipulation.
Conclusion
For element‑wise updates inside loops, prefer at / iat to achieve dramatic speed gains. Reserve loc / iloc for vectorized operations or when you need to access multiple rows or columns simultaneously.
Python Programming Learning Circle
A global community of Chinese Python developers offering technical articles, columns, original video tutorials, and problem sets. Topics include web full‑stack development, web scraping, data analysis, natural language processing, image processing, machine learning, automated testing, DevOps automation, and big data.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
