Last modified: May 08, 2026 By Alexander Williams
Polars DataFrame Sorting & Slicing Guide
Data analysis often starts with organizing your data. In Polars, sorting and slicing are fundamental operations. They help you find patterns, view top values, and prepare data for further analysis. This guide will show you how to sort rows by columns and slice subsets of your DataFrame. We’ll use simple examples and clear code. Let’s dive in.
Why Sort and Slice?
Sorting arranges your data in a meaningful order. You might sort by date, sales, or customer ID. Slicing lets you grab a specific chunk of rows, like the first ten or a range. Together, they give you control over how you view and use your data.
Polars is built for speed. Its sorting and slicing operations are optimized for large datasets. You can perform these tasks without worrying about memory or performance issues. This makes Polars a great choice for data scientists and engineers.
Sorting a DataFrame
To sort a DataFrame, use the sort() method. You pass the column name you want to sort by. By default, it sorts in ascending order. For descending order, set descending=True.
Let’s create a simple DataFrame first.
import polars as pl
# Create a sample DataFrame
df = pl.DataFrame({
"name": ["Alice", "Bob", "Charlie", "David"],
"age": [25, 30, 35, 28],
"salary": [50000, 60000, 55000, 52000]
})
print("Original DataFrame:")
print(df)
Output:
Original DataFrame:
shape: (4, 3)
┌─────────┬─────┬────────┐
│ name ┆ age ┆ salary │
│ --- ┆ --- ┆ --- │
│ str ┆ i64 ┆ i64 │
╞═════════╪═════╪════════╡
│ Alice ┆ 25 ┆ 50000 │
│ Bob ┆ 30 ┆ 60000 │
│ Charlie ┆ 35 ┆ 55000 │
│ David ┆ 28 ┆ 52000 │
└─────────┴─────┴────────┘
Now, sort by age in ascending order.
# Sort by age ascending
sorted_df = df.sort("age")
print("Sorted by age (ascending):")
print(sorted_df)
Output:
Sorted by age (ascending):
shape: (4, 3)
┌─────────┬─────┬────────┐
│ name ┆ age ┆ salary │
│ --- ┆ --- ┆ --- │
│ str ┆ i64 ┆ i64 │
╞═════════╪═════╪════════╡
│ Alice ┆ 25 ┆ 50000 │
│ David ┆ 28 ┆ 52000 │
│ Bob ┆ 30 ┆ 60000 │
│ Charlie ┆ 35 ┆ 55000 │
└─────────┴─────┴────────┘
Sort by salary in descending order.
# Sort by salary descending
sorted_salary = df.sort("salary", descending=True)
print("Sorted by salary (descending):")
print(sorted_salary)
Output:
Sorted by salary (descending):
shape: (4, 3)
┌─────────┬─────┬────────┐
│ name ┆ age ┆ salary │
│ --- ┆ --- ┆ --- │
│ str ┆ i64 ┆ i64 │
╞═════════╪═════╪════════╡
│ Bob ┆ 30 ┆ 60000 │
│ Charlie ┆ 35 ┆ 55000 │
│ David ┆ 28 ┆ 52000 │
│ Alice ┆ 25 ┆ 50000 │
└─────────┴─────┴────────┘
Tip: You can sort by multiple columns. Pass a list of column names. For example, df.sort(["age", "salary"]) sorts by age first, then by salary.
Sorting with Expressions
Polars also supports sorting using expressions. This is powerful when you need to sort by a computed column. Use the pl.col() function inside sort().
# Sort by a computed column: salary per age ratio
sorted_expr = df.sort(pl.col("salary") / pl.col("age"))
print("Sorted by salary/age ratio:")
print(sorted_expr)
Output:
Sorted by salary/age ratio:
shape: (4, 3)
┌─────────┬─────┬────────┐
│ name ┆ age ┆ salary │
│ --- ┆ --- ┆ --- │
│ str ┆ i64 ┆ i64 │
╞═════════╪═════╪════════╡
│ Alice ┆ 25 ┆ 50000 │
│ David ┆ 28 ┆ 52000 │
│ Charlie ┆ 35 ┆ 55000 │
│ Bob ┆ 30 ┆ 60000 │
└─────────┴─────┴────────┘
Slicing Rows
Slicing extracts a contiguous block of rows. Use the slice() method. It takes two arguments: the starting offset and the length. If you only want the first few rows, use head().
# Get the first 2 rows
first_two = df.head(2)
print("First two rows:")
print(first_two)
Output:
First two rows:
shape: (2, 3)
┌───────┬─────┬────────┐
│ name ┆ age ┆ salary │
│ --- ┆ --- ┆ --- │
│ str ┆ i64 ┆ i64 │
╞═══════╪═════╪════════╡
│ Alice ┆ 25 ┆ 50000 │
│ Bob ┆ 30 ┆ 60000 │
└───────┴─────┴────────┘
To get rows from index 1 to 3 (exclusive), use slice().
# Slice rows 1 to 3 (offset 1, length 3)
sliced = df.slice(1, 3)
print("Rows 1 to 3:")
print(sliced)
Output:
Rows 1 to 3:
shape: (3, 3)
┌─────────┬─────┬────────┐
│ name ┆ age ┆ salary │
│ --- ┆ --- ┆ --- │
│ str ┆ i64 ┆ i64 │
╞═════════╪═════╪════════╡
│ Bob ┆ 30 ┆ 60000 │
│ Charlie ┆ 35 ┆ 55000 │
│ David ┆ 28 ┆ 52000 │
└─────────┴─────┴────────┘
You can also use negative offsets. df.slice(-2, 2) gets the last two rows.
Filtering vs Slicing
Remember, slicing is not the same as filtering. Slicing uses row positions. Filtering uses conditions. For example, df.filter(pl.col("age") > 30) returns rows where age is greater than 30. Slicing just takes a chunk of rows regardless of their values.
For more on filtering, check our guide on Select Columns & Filter Rows in Polars.
Combining Sort and Slice
You often need to sort first, then slice. For example, get the top 3 highest salaries.
# Sort by salary descending, then take top 3
top_salaries = df.sort("salary", descending=True).head(3)
print("Top 3 salaries:")
print(top_salaries)
Output:
Top 3 salaries:
shape: (3, 3)
┌─────────┬─────┬────────┐
│ name ┆ age ┆ salary │
│ --- ┆ --- ┆ --- │
│ str ┆ i64 ┆ i64 │
╞═════════╪═════╪════════╡
│ Bob ┆ 30 ┆ 60000 │
│ Charlie ┆ 35 ┆ 55000 │
│ David ┆ 28 ┆ 52000 │
└─────────┴─────┴────────┘
This pattern is very common in data analysis. It gives you the best or worst performers quickly.
Working with Large DataFrames
When your data is huge, sorting and slicing are still fast in Polars. The library uses lazy evaluation by default. If you want to chain many operations, use lazy() for even better performance. But for simple tasks, eager execution works fine.
For more on exploring data, see Explore Data with Polars Shape, Head.
Practical Example: Analyzing Sales Data
Let’s simulate a sales dataset. We’ll sort by date and slice the first week.
# Create sales data
sales = pl.DataFrame({
"date": ["2025-01-01", "2025-01-02", "2025-01-03", "2025-01-04", "2025-01-05"],
"revenue": [100, 200, 150, 300, 250],
"region": ["North", "South", "East", "West", "North"]
})
# Sort by date
sales_sorted = sales.sort("date")
print("Sales sorted by date:")
print(sales_sorted)
# Get first 3 rows (first 3 days)
first_3_days = sales_sorted.head(3)
print("First 3 days:")
print(first_3_days)
Output:
Sales sorted by date:
shape: (5, 3)
┌────────────┬─────────┬────────┐
│ date ┆ revenue ┆ region │
│ --- ┆ --- ┆ --- │
│ str ┆ i64 ┆ str │
╞════════════╪═════════╪════════╡
│ 2025-01-01 ┆ 100 ┆ North │
│ 2025-01-02 ┆ 200 ┆ South │
│ 2025-01-03 ┆ 150 ┆ East │
│ 2025-01-04 ┆ 300 ┆ West │
│ 2025-01-05 ┆ 250 ┆ North │
└────────────┴─────────┴────────┘
First 3 days:
shape: (3, 3)
┌────────────┬─────────┬────────┐
│ date ┆ revenue ┆ region │
│ --- ┆ --- ┆ --- │
│ str ┆ i64 ┆ str │
╞════════════╪═════════╪════════╡
│ 2025-01-01 ┆ 100 ┆ North │
│ 2025-01-02 ┆ 200 ┆ South │
│ 2025-01-03 ┆ 150 ┆ East │
└────────────┴─────────┴────────┘
Sorting with Null Values
Polars handles nulls gracefully. By default, nulls are placed at the end when sorting ascending. You can change this with the nulls_last parameter.
# DataFrame with nulls
df_nulls = pl.DataFrame({
"value": [3, None, 1, 2]
})
# Sort ascending, nulls last
sorted_nulls = df_nulls.sort("value")
print("Sorted with nulls last:")
print(sorted_nulls)
# Sort ascending, nulls first
sorted_nulls_first = df_nulls.sort("value", nulls_last=False)
print("Sorted with nulls first:")
print(sorted_nulls_first)
Output:
Sorted with nulls last:
shape: (4, 1)
┌───────┐
│ value │
│ --- │
│ i64 │
╞═══════╡
│ 1 │
│ 2 │
│ 3 │
│ null │
└───────┘
Sorted with nulls first:
shape: (4, 1)
┌───────┐
│ value │
│ --- │
│ i64 │
╞═══════╡
│ null │
│ 1 │
│ 2 │
│ 3 │
└───────┘
Using Polars Expressions for Advanced Slicing
You can also slice using expressions with filter(). For example, to get rows where the index is within a range, use pl.int_range(). This is useful for complex conditions.
# Use filter with row index
sliced_expr = df.filter(pl.int_range(0, pl.count()).is_between(1, 3))
print("Rows 1 to 3 using expression:")
print(sliced_expr)
Output:
Rows 1 to 3 using expression:
shape: (3, 3)
┌─────────┬─────┬────────┐
│ name ┆ age ┆ salary │
│ --- ┆ --- ┆ --- │
│ str ┆ i64 ┆ i64 │
╞═════════╪═════╪════════╡
│ Bob ┆ 30 ┆ 60000 │
│ Charlie ┆ 35 ┆ 55000 │
│ David ┆ 28 ┆ 52000 │
└─────────┴─────┴────────┘
Additional Resources
To deepen your understanding of Polars, explore these guides:
- Polars DataFrames and Series Guide – Learn the basics of DataFrames and Series.
- Polars Columns: Add, Rename & Drop – Master column operations.
Conclusion
Sorting and slicing are essential tools in Polars. They let you organize and extract data efficiently. Use sort() to order rows by one or more columns. Use slice() or head() to grab specific rows. Combine them for powerful data analysis, like finding top performers. Polars makes these operations fast and intuitive. Practice with your own data to get comfortable. Happy coding!