npx skills add ...
npx skills add davila7/claude-code-templates --skill polars
npx skills add davila7/claude-code-templates --skill polars
Fast DataFrame library (Apache Arrow). Select, filter, group_by, joins, lazy evaluation, CSV/Parquet I/O, expression API, for high-performance data analysis workflows.
Polars is a lightning-fast DataFrame library for Python and Rust built on Apache Arrow. Work with Polars' expression-based API, lazy evaluation framework, and high-performance data manipulation capabilities for efficient data processing, pandas migration, and data pipeline optimization.
Install Polars:
Basic DataFrame creation and operations:
Expressions are the fundamental building blocks of Polars operations. They describe transformations on data and can be composed, reused, and optimized.
Key principles:
pl.col("column_name") to reference columnsExample:
Eager (DataFrame): Operations execute immediately
Lazy (LazyFrame): Operations build a query plan, optimized before execution
When to use lazy:
Benefits of lazy evaluation:
For detailed concepts, load references/core_concepts.md.
Select and manipulate columns:
Filter rows by conditions:
Add or modify columns while preserving existing ones:
Group data and compute aggregations:
For detailed operation patterns, load references/operations.md.
Common aggregations within group_by context:
pl.len() - count rowspl.col("x").sum() - sum valuespl.col("x").mean() - averagepl.col("x").min() / pl.col("x").max() - extremespl.first() / pl.last() - first/last valuesover()Apply aggregations while preserving row count:
Mapping strategies:
group_to_rows (default): Preserves original row orderexplode: Faster but groups rows togetherjoin: Creates list columnsPolars supports reading and writing:
CSV:
Parquet (recommended for performance):
JSON:
For comprehensive I/O documentation, load references/io_guide.md.
Combine DataFrames:
Stack DataFrames:
Reshape data:
For detailed transformation examples, load references/transformations.md.
Polars offers significant performance improvements over pandas with a cleaner API. Key differences:
| Operation | Pandas | Polars |
|---|---|---|
| Select column | df["col"] | df.select("col") |
| Filter | df[df["col"] > 10] | df.filter(pl.col("col") > 10) |
| Add column | df.assign(x=...) | df.with_columns(x=...) |
| Group by | df.groupby("col").agg(...) | df.group_by("col").agg(...) |
| Window | df.groupby("col").transform(...) | df.with_columns(...).over("col") |
Pandas sequential (slow):
Polars parallel (fast):
For comprehensive migration guide, load references/pandas_migration.md.
Use lazy evaluation for large datasets:
Avoid Python functions in hot paths:
.map_elements() only when necessaryUse streaming for very large data:
Select only needed columns early:
Use appropriate data types:
Conditional operations:
Column operations across multiple columns:
Null handling:
For additional best practices and patterns, load references/best_practices.md.
This skill includes comprehensive reference documentation:
core_concepts.md - Detailed explanations of expressions, lazy evaluation, and type systemoperations.md - Comprehensive guide to all common operations with examplespandas_migration.md - Complete migration guide from pandas to Polarsio_guide.md - Data I/O operations for all supported formatstransformations.md - Joins, concatenation, pivots, and reshaping operationsbest_practices.md - Performance optimization tips and common patternsLoad these references as needed when users require detailed information about specific topics.
# Expression-based computation
df.select(
pl.col("name"),
(pl.col("age") * 12).alias("age_in_months")
)df = pl.read_csv("file.csv") # Reads immediately
result = df.filter(pl.col("age") > 25) # Executes immediatelylf = pl.scan_csv("file.csv") # Doesn't read yet
result = lf.filter(pl.col("age") > 25).select("name", "age")
df = result.collect() # Now executes optimized query# Select specific columns
df.select("name", "age")
# Select with expressions
df.select(
pl.col("name"),
(pl.col("age") * 2).alias("double_age")
)
# Select all columns matching a pattern
df.select(pl.col("^.*_id$"))# Single condition
df.filter(pl.col("age") > 25)
# Multiple conditions (cleaner than using &)
df.filter(
pl.col("age") > 25,
pl.col("city") == "NY"
)
# Complex conditions
df.filter(
(pl.col("age") > 25) | (pl.col("city") == "LA")
)# Add new columns
df.with_columns(
age_plus_10=pl.col("age") + 10,
name_upper=pl.col("name").str.to_uppercase()
)
# Parallel computation (all columns computed in parallel)
df.with_columns(
pl.col("value") * 10,
pl.col("value") * 100,
)# Basic grouping
df.group_by("city").agg(
pl.col("age").mean().alias("avg_age"),
pl.len().alias("count")
)
# Multiple group keys
df.group_by("city", "department").agg(
pl.col("salary").sum()
)
# Conditional aggregations
df.group_by("city").agg(
(pl.col("age") > 30).sum().alias("over_30")
)# Add group statistics to each row
df.with_columns(
avg_age_by_city=pl.col("age").mean().over("city"),
rank_in_city=pl.col("salary").rank().over("city")
)
# Multiple grouping columns
df.with_columns(
group_avg=pl.col("value").mean().over("category", "region")
)# Eager
df = pl.read_csv("file.csv")
df.write_csv("output.csv")
# Lazy (preferred for large files)
lf = pl.scan_csv("file.csv")
result = lf.filter(...).select(...).collect()df = pl.read_parquet("file.parquet")
df.write_parquet("output.parquet")df = pl.read_json("file.json")
df.write_json("output.json")# Inner join
df1.join(df2, on="id", how="inner")
# Left join
df1.join(df2, on="id", how="left")
# Join on different column names
df1.join(df2, left_on="user_id", right_on="id")# Vertical (stack rows)
pl.concat([df1, df2], how="vertical")
# Horizontal (add columns)
pl.concat([df1, df2], how="horizontal")
# Diagonal (union with different schemas)
pl.concat([df1, df2], how="diagonal")# Pivot (wide format)
df.pivot(values="sales", index="date", columns="product")
# Unpivot (long format)
df.unpivot(index="id", on=["col1", "col2"])df.assign(
col_a=lambda df_: df_.value * 10,
col_b=lambda df_: df_.value * 100
)df.with_columns(
col_a=pl.col("value") * 10,
col_b=pl.col("value") * 100,
)