Expressions beat map_elements in Python
map_elements drops into Python per row: correct, but the slow path.
import polars as pl
frame = pl.DataFrame({"tpm": [104, 88, 96]})
slow = frame.with_columns(
pl.col("tpm").map_elements(lambda n: n * 2, return_dtype=pl.Int64)
.alias("doubled_python"))
fast = frame.with_columns((pl.col("tpm") * 2).alias("doubled_expr"))
print(slow)
print(fast)
print(slow["doubled_python"].to_list() == fast["doubled_expr"].to_list())
How it works
- An expression stays in Rust and parallelises.
map_elementsneeds a return dtype to stay typed.- Reach for it only when no expression exists.
Keywords and builtins used here
aslambdaprint
The run, in numbers
- Lines
- 13
- Characters to type
- 355
- Tokens
- 120
- Three-star pace
- 115 tpm
At the three-star pace of 115 tokens a minute, this run takes about 63 seconds.
Step 4 of 4 in Lazy & SQL, step 28 of 32 in Polars.