Slicing Columns in Pandas – Best Practices for Selecting Columns 2026

Data Manipulation Mar 18, 2026

Slicing Columns in Pandas – Best Practices for Selecting Columns 2026

Selecting and slicing columns efficiently is a fundamental skill in Pandas data manipulation. In 2026, knowing the different ways to slice columns helps you write cleaner, faster, and more readable code.

TL;DR — Recommended Column Selection Methods

  • df[["col1", "col2"]] – Best for selecting specific columns by name
  • df.loc[:, "col1":"col3"] – Label-based slicing (inclusive)
  • df.iloc[:, 0:5] – Position-based slicing
  • df.filter() – Flexible pattern-based selection

1. Basic Column Selection

import pandas as pd

# Create a small demo file so this example runs as-is
# (in your project, sales_data.csv is your real export)
import numpy as np
rng = np.random.default_rng(42)
n = 60
pd.DataFrame({
    "order_date": pd.date_range("2026-01-01", periods=n, freq="3D"),
    "customer_id": rng.integers(101, 121, n),
    "customer_name": rng.choice([" ana", "ben ", "chen", "dana"], n),
    "product_id": rng.integers(1, 9, n),
    "region": rng.choice(["North", "South", "East", "West"], n),
    "category": rng.choice(["Electronics", "Computers", "Books", "Home"], n),
    "payment_method": rng.choice(["card", "cash", "wallet"], n),
    "segment": rng.choice(["consumer", "business"], n),
    "quantity": rng.integers(1, 6, n),
    "amount": rng.uniform(50, 2500, n).round(2),
    "discount": rng.choice([0.0, 0.05, 0.1, 0.2], n),
}).assign(
    price=lambda d: (d["amount"] / d["quantity"]).round(2),
    profit=lambda d: (d["amount"] * rng.uniform(0.05, 0.3, n)).round(2),
).assign(
    ship_date=lambda d: d["order_date"] + pd.Timedelta(days=2),
    status=lambda d: np.where(d["amount"] > 2000, "priority", "standard"),
).to_csv("sales_data.csv", index=False)

df = pd.read_csv("sales_data.csv", parse_dates=["order_date"])

# Most common and recommended way
sales_info = df[["order_date", "customer_id", "amount", "region"]]

# Select multiple columns by name
key_metrics = df[["amount", "quantity", "profit"]]

2. Label-based Column Slicing with .loc[]

# Slice columns by label (inclusive)
financial_cols = df.loc[:, "order_date":"profit"]

# Select from "customer_id" to "region" inclusive
customer_slice = df.loc[:, "customer_id":"region"]

3. Position-based Slicing with .iloc[]

# First 5 columns
first_five = df.iloc[:, :5]

# Columns from position 2 to 7 (exclusive end)
middle_cols = df.iloc[:, 2:8]

# Last 3 columns
last_three = df.iloc[:, -3:]

4. Advanced Column Selection with filter()

# Select columns containing a pattern
amount_cols = df.filter(like="amount")

# Select columns starting with "cust"
customer_cols = df.filter(regex="^cust")

# Select columns ending with "_id"
id_cols = df.filter(regex="_id$")

5. Best Practices in 2026

  • Use df[["col1", "col2"]] when you know exact column names — it's the most readable
  • Use .loc[:, "start":"end"] for label-based range slicing
  • Use .iloc[:, start:end] when working by position
  • Use .filter() with like or regex for pattern-based selection
  • Combine with .reindex() or column lists for consistent column order

Selecting Columns Clearly

Column selection decides which variables continue through your analysis, so it pays to be explicit. A single name in brackets returns a Series, a list of names returns a DataFrame, and df.loc[:, "a":"c"] returns a contiguous range of columns by label, with both ends included.

For pattern-based selection, df.filter(like=...) and df.select_dtypes() avoid long hand-typed lists. Positional selection with iloc is useful when column names are unknown, but it breaks silently if the column order changes, so prefer names in production code.

Worked Example: Four Column Selections

The small orders table below shows each approach and the type of object it returns.

import pandas as pd

df = pd.DataFrame({
    "order_id": [1, 2, 3],
    "region": ["North", "South", "East"],
    "price_usd": [19.5, 42.0, 7.25],
    "tax_usd": [1.6, 3.4, 0.6],
    "quantity": [2, 1, 5],
})

print(type(df["region"]).__name__)
print(df[["region", "quantity"]])
print(df.loc[:, "price_usd":"quantity"])
print(df.filter(like="_usd").columns.tolist())
print(df.select_dtypes("number").columns.tolist())

Notice that the label range includes quantity, the stop label, unlike positional slices. filter() and select_dtypes() adapt automatically when new matching columns are added later.

Practical Tips

When a script depends on specific columns, check that they exist before selecting them, for example with set(cols) - set(df.columns). A clear error at the start is easier to fix than a KeyError deep inside a pipeline.

Common Mistakes

  • Expecting df["a", "b"] to select two columns; it needs a list.
  • Assuming a loc column range excludes the stop label.
  • Relying on iloc positions after columns have been reordered.
  • Modifying a column subset and expecting the original to change.

Quick Summary

  • df["col"] returns a Series; df[[...]] returns a DataFrame.
  • loc label ranges include both ends.
  • filter() and select_dtypes() select by pattern or type.
  • Prefer names over positions for stable code.

Conclusion

Slicing columns effectively is essential for clean data manipulation. In 2026, the best practice is to use explicit column selection with df[["col1", "col2"]] for readability, .loc[] for label ranges, .iloc[] for positional slicing, and .filter() for pattern matching. Choosing the right method for each situation will make your code more maintainable and efficient.

Next steps:

  • Review your current code and replace any loose column selection with explicit, readable slicing techniques

Related Tutorials

Share:
Last updated: March 2026
Built-in Functions in Python 2026 str() in Python 2026: String Conversion + Modern Formatting & Best Practices memoryview with JAX in Python 2026: Zero-Copy NumPy → JAX Array Interop + Efficient ML Examples memoryview with TensorFlow in Python 2026: Zero-Copy NumPy → Tensor Interop + GPU Pinning & ML Examples memoryview with TensorFlow in Python 2026: Zero-Copy NumPy → Tensor Interop + ML Examples memoryview with NumPy & PyTorch in Python 2026: Zero-Copy Views, Efficient Slicing & ML Interop Examples memoryview with NumPy in Python 2026: Zero-Copy Views, Efficient Slicing & Real ML Examples memoryview() in Python 2026: Zero-Copy Magic for Large Binary Data + Real Examples import() in Python 2026: How It Works, Security Risks & Modern Alternatives (importlib) zip() in Python 2026: How to Use It, strict=True Behavior & Real-World Examples vars() in Python 2026: Accessing Object Namespace + Modern Introspection Patterns type() in Python 2026: Dynamic Type Inspection & Object Creation + Modern Patterns tuple() in Python 2026: Immutable Sequences + Modern Patterns & Best Practices super() in Python 2026: Method Resolution & Modern Inheritance Patterns sum() in Python 2026: Summing Iterables + Modern Numeric Patterns & Best Practices staticmethod() in Python 2026: Static Methods, Utility Functions & Modern Best Practices sorted() in Python 2026: Sorting Iterables + Modern Patterns & Best Practices slice() in Python 2026: Creating Slice Objects + Modern Patterns & Best Practices setattr() in Python 2026: Dynamic Attribute Setting + Modern Patterns & Safety set() in Python 2026: Mutable Sets Creation + Modern Patterns & Best Practices