Simplifying conditional Polars Expressions with Python ๐ ๐ปโโ๏ธ
Project description
polarIFy: Simplifying conditional Polars Expressions with Python ๐ ๐ปโโ๏ธ
Welcome to polarIFy, a Python function decorator that simplifies the way you write logical statements for Polars. With polarIFy, you can use Python's language structures like if / elif / else statements and transform them into pl.when(..).then(..).otherwise(..) statements. This makes your code more readable and less cumbersome to write. ๐
๐ฏ Usage
polarIFy can automatically transform Python functions using if / elif / else statements into Polars expressions.
Basic Transformation
Here's an example:
@polarify
def signum(x: pl.Expr) -> pl.Expr:
s = 0
if x > 0:
s = 1
elif x < 0:
s = -1
return s
This gets transformed into:
def signum(x: pl.Expr) -> pl.Expr:
return pl.when(x > 0).then(1).otherwise(pl.when(x < 0).then(-1).otherwise(0))
Handling Multiple Statements
polarIFy can also handle multiple statements like:
@polarify
def multiple_if_statement(x: pl.Expr) -> pl.Expr:
a = 1 if x > 0 else 5
b = 2 if x < 0 else 2
return a + b
which becomes:
def multiple_if_statement(x):
return pl.when(x > 0).then(1).otherwise(5) + pl.when(x < 0).then(2).otherwise(2)
Handling Nested Statements
Additionally, it can handle nested statements:
@polarify
def nested_if_else(x: pl.Expr) -> pl.Expr:
if x > 0:
if x > 1:
s = 2
else:
s = 1
elif x < 0:
s = -1
else:
s = 0
return s
which becomes:
def nested_if_else(x: pl.Expr) -> pl.Expr:
return pl.when(x > 0).then(pl.when(x > 1).then(2).otherwise(1)).otherwise(pl.when(x < 0).then(-1).otherwise(0))
So you can still write readable row-wise python code while the @polarify decorator transforms it into a function that works with efficient polars expressions.
Using a polarifyd function
import polars as pl
from polarify import polarify
@polarify
def complicated_operation(x: pl.Expr) -> pl.Expr:
k = 0
c = 2
if x > 0:
k = 1
c = 0
if x < 10:
c = 1
elif x < 0:
k = -1
return k * c
df = pl.DataFrame({"x": [-1, 1, 5, 10]})
result = df.select(pl.col("x"), complicated_operation(pl.col("x")))
print(result)
# shape: (4, 2)
# โโโโโโโฌโโโโโโโโโโ
# โ x โ literal โ
# โ --- โ --- โ
# โ i64 โ i32 โ
# โโโโโโโชโโโโโโโโโโก
# โ -1 โ -2 โ
# โ 1 โ 1 โ
# โ 5 โ 1 โ
# โ 10 โ 0 โ
# โโโโโโโดโโโโโโโโโโ
Displaying the transpiled polars expression
You can also display the transpiled polars expression by calling the transform_func_to_new_source method:
from polarify import transform_func_to_new_source
def signum(x):
s = 0
if x > 0:
s = 1
elif x < 0:
s = -1
return s
print(f"Original function:\n{inspect.getsource(signum)}")
# Original function:
# def signum(x):
# s = 0
# if x > 0:
# s = 1
# elif x < 0:
# s = -1
# return s
print(f"Transformed function:\n{transform_func_to_new_source(signum)}")
# Transformed function:
# def signum_polarified(x):
# import polars as pl
# return pl.when(x > 0).then(1).otherwise(pl.when(x < 0).then(-1).otherwise(0))
TODO: complicated example with nested functions
โ๏ธ How It Works
polarIFy achieves this by parsing the AST (Abstract Syntax Tree) of the function and transforming the body into a Polars expression by inlining the different branches. To get a more detailed understanding of what's happening under the hood, check out our blog post explaining how polarify works!
๐ฟ Installation
conda
conda install -c conda-forge polarify
# or micromamba
micromamba install -c conda-forge polarify
# or pixi
pixi add polarify
pip
pip install polarify
โ ๏ธ Limitations
polarIFy is still in an early stage of development and doesn't support the full Python language. Here's a list of the currently supported and unsupported operations:
Supported operations
if / else / elifstatements- binary operations (like
+,==,>,&,|, ...) - unary operations (like
~,-,not, ...) (TODO) - assignments (like
x = 1) - polars expressions (like
pl.col("x"), TODO) - side-effect free functions that return a polars expression (can be generated by
@polarify) (TODO) matchstatements
Unsupported operations
forloopswhileloopsbreakstatements:=walrus operator- dictionary mappings in
matchstatements - list matching in
matchstatements - star patterns in `match statements
- functions with side-effects (
print,pl.write_csv, ...)
๐ Benchmarks
TODO: Add some benchmarks
๐ฅ Development installation
pixi install
pixi run postinstall
pixi run test
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file polarify-0.2.1.tar.gz.
File metadata
- Download URL: polarify-0.2.1.tar.gz
- Upload date:
- Size: 11.2 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.12.9
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
36770de45a20ff311c0891045babb7036653bb65705dacbac64f8fc2b9dc584c
|
|
| MD5 |
42be3595e50a10c42e00ffad871a5897
|
|
| BLAKE2b-256 |
0c2373443eca1f1a3836fcf9cae76f4a984fd074e49e335106956cdb73071af3
|
Provenance
The following attestation bundles were made for polarify-0.2.1.tar.gz:
Publisher:
build.yml on Quantco/polarify
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
polarify-0.2.1.tar.gz -
Subject digest:
36770de45a20ff311c0891045babb7036653bb65705dacbac64f8fc2b9dc584c - Sigstore transparency entry: 213323417
- Sigstore integration time:
-
Permalink:
Quantco/polarify@8325d8cac05889e93bdeb0196882ce5ea50abb64 -
Branch / Tag:
refs/heads/main - Owner: https://github.com/Quantco
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
build.yml@8325d8cac05889e93bdeb0196882ce5ea50abb64 -
Trigger Event:
push
-
Statement type:
File details
Details for the file polarify-0.2.1-py3-none-any.whl.
File metadata
- Download URL: polarify-0.2.1-py3-none-any.whl
- Upload date:
- Size: 9.2 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.12.9
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
7289ee94094092668d49847f200cc59b98fb480abd720c9dc37df8e74ce422cd
|
|
| MD5 |
2db59f01834166a36aae70e61a48790c
|
|
| BLAKE2b-256 |
be63355c7290618a8bc1777a6ff25bd19c2607423fb8a7f98ffd61d549625bce
|
Provenance
The following attestation bundles were made for polarify-0.2.1-py3-none-any.whl:
Publisher:
build.yml on Quantco/polarify
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
polarify-0.2.1-py3-none-any.whl -
Subject digest:
7289ee94094092668d49847f200cc59b98fb480abd720c9dc37df8e74ce422cd - Sigstore transparency entry: 213323418
- Sigstore integration time:
-
Permalink:
Quantco/polarify@8325d8cac05889e93bdeb0196882ce5ea50abb64 -
Branch / Tag:
refs/heads/main - Owner: https://github.com/Quantco
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
build.yml@8325d8cac05889e93bdeb0196882ce5ea50abb64 -
Trigger Event:
push
-
Statement type: