.loc[] + slicing is one of the most powerful combos in pandas — it lets you select rows and columns by label (or condition) with elegant, readable range slicing. Unlike .iloc[] (position-based), .loc[] works with index/column labels and supports inclusive slicing, boolean masks, and lists, making it the go-to for most real-world work.
In 2026, this pattern remains essential for filtering, feature selection, reporting, and time-series analysis. Here’s a practical guide with real examples you can copy and adapt.
1. Basic Setup & Sample Data
import pandas as pd
data = {
'Name': ['John', 'Mary', 'Peter', 'Anna', 'Mike'],
'Age': [25, 32, 18, 47, 23],
'Salary': [50000, 80000, 35000, 65000, 45000],
'Department': ['Sales', 'Engineering', 'Sales', 'HR', 'Engineering']
}
df = pd.DataFrame(data, index=['emp1', 'emp2', 'emp3', 'emp4', 'emp5'])
print(df)
2. Label-Based Row + Column Slicing with .loc[]
.loc[row_labels, column_labels] — inclusive on both ends, supports ranges, lists, and conditions.
# Rows 'emp2' to 'emp4' (inclusive), columns 'Age' to 'Salary'
slice_combo = df.loc['emp2':'emp4', 'Age':'Salary']
print(slice_combo)
Output:
Age Salary
emp2 32 80000
emp3 18 35000
emp4 47 65000
# Specific rows + range of columns
specific_rows = df.loc[['emp1', 'emp3', 'emp5'], 'Name':'Department']
3. Combining .loc[] with Boolean Conditions (Power Move)
Filter rows by condition, then slice columns — most common real-world pattern.
# Employees over 30, only Name, Salary, Department
high_age = df.loc[df['Age'] > 30, ['Name', 'Salary', 'Department']]
print(high_age)
Output:
Name Salary Department
emp2 Mary 80000 Engineering
emp4 Anna 65000 HR
# Multiple conditions + column slice
sales_high = df.loc[
(df['Department'] == 'Sales') & (df['Salary'] > 40000),
'Name':'Salary'
]
4. Real-World Use Cases (2026 Examples)
Time-series range + column selection
# df with datetime index
timeseries = df.loc['2025-01-01':'2025-06-30', ['close', 'volume']]
Feature selection after filtering
model_features = df.loc[df['Age'] > 25, 'Salary':'Bonus']
Exclude outliers, keep key columns
clean_df = df.loc[~df['Salary'].between(30000, 50000), ['Name', 'Salary', 'Department']]
5. Modern Alternative in 2026: Polars
For large datasets, Polars is often faster and more memory-efficient — filtering + selection syntax is very similar.
import polars as pl
df_pl = pl.DataFrame(data)
# Rows where Age > 30, columns 'Name', 'Salary', 'Department'
high_age_pl = df_pl.filter(pl.col("Age") > 30).select(["Name", "Salary", "Department"])
print(high_age_pl)
Best Practices & Common Pitfalls
- Prefer
.loc[]with labels/conditions — more readable and safe than.iloc[] - Always use square brackets for column lists:
[['A', 'B']]not['A', 'B'] - Range slicing is inclusive —
'a':'c'includes 'c' - Boolean masks go in row position — column selection in second position
- Chain with
.query()for complex conditions — often cleaner than long masks - For huge data, prefer Polars filtering + selection — it's faster and more memory-efficient
Conclusion
The .loc[] + slicing combo is a true power move in pandas — it lets you filter rows by condition or label, then immediately select the exact columns you need in one readable line. In 2026, prefer .loc[] for most work, use boolean masks for filtering, and reach for Polars when performance is critical. Master row masks, column lists/ranges, and chaining, and you'll manipulate DataFrames with speed and clarity every time.
Next time you need filtered rows with specific columns — use .loc[] + slicing first.