22 个版本 (破坏性更新)

0.16.1 2024 年 8 月 16 日
0.15.0 2024 年 6 月 22 日
0.12.0 2024 年 2 月 29 日
0.9.0 2023 年 11 月 18 日
0.2.0 2023 年 2 月 15 日

#76 in Rust 模式

Download history 7181/week @ 2024-05-04 8244/week @ 2024-05-11 7555/week @ 2024-05-18 11053/week @ 2024-05-25 8470/week @ 2024-06-01 10572/week @ 2024-06-08 13723/week @ 2024-06-15 13094/week @ 2024-06-22 14520/week @ 2024-06-29 17685/week @ 2024-07-06 18384/week @ 2024-07-13 23261/week @ 2024-07-20 29909/week @ 2024-07-27 21385/week @ 2024-08-03 24288/week @ 2024-08-10 29128/week @ 2024-08-17

每月 109,645 次下载
7 crate 中使用

MIT 许可证

47KB
851

1. Polars 的共享库插件

有关此功能的文档也可在 Polars 用户指南 中找到。这是新功能,应优先考虑,因为它将绕过 GIL,并将成为我们支持扩展 Polars 的方式。

并行化和优化由默认的 Polars 运行时管理。该运行时将调用插件函数。插件函数是独立编译的。

因此,我们可以使 Polars 更加精简,也许可以添加对 polars-distancepolars-geopolars-ml 等的支持。这些可以提供专门的表达式,并且不必过于担心代码膨胀,因为它们可以可选安装。

想法是在另一个 Rust crate 中使用 proc_macro polars_expr 定义表达式。

该宏可能具有以下属性之一

  • output_type -> 定义该表达式的输出类型
  • output_type_func -> 定义一个函数,该函数根据输入类型计算输出类型。
  • output_type_func_with_kwargs -> 定义一个函数,该函数根据输入类型和关键字参数计算输出类型。

以下是一个将任何字符串转换为 猪拉丁String 转换表达式示例

fn pig_latin_str(value: &str, capitalize: bool, output: &mut String) {
    if let Some(first_char) = value.chars().next() {
        if capitalize {
            for c in value.chars().skip(1).map(|char| char.to_uppercase()) {
                write!(output, "{c}").unwrap()
            }
            write!(output, "AY").unwrap()
        } else {
            let offset = first_char.len_utf8();
            write!(output, "{}{}ay", &value[offset..], first_char).unwrap()
        }
    }
}

#[derive(Deserialize)]
struct PigLatinKwargs {
    capitalize: bool,
}

#[polars_expr(output_type=String)]
fn pig_latinnify(inputs: &[Series], kwargs: PigLatinKwargs) -> PolarsResult<Series> {
    let ca = inputs[0].str()?;
    let out: StringChunked =
        ca.apply_into_string_amortized(|value, output| pig_latin_str(value, kwargs.capitalize, output));
    Ok(out.into_series())
}

这然后可以在 Python 端公开

import polars as pl
from polars.type_aliases import IntoExpr
from polars.utils.udfs import _get_shared_lib_location

from expression_lib.utils import parse_into_expr

lib = _get_shared_lib_location(__file__)


def pig_latinnify(expr: IntoExpr, capitalize: bool = False) -> pl.Expr:
    expr = parse_into_expr(expr)
    return expr.register_plugin(
        lib=lib,
        symbol="pig_latinnify",
        is_elementwise=True,
        kwargs={"capitalize": capitalize},
    )

编译/发货后即可使用

import polars as pl
from expression_lib import language

df = pl.DataFrame({
    "names": ["Richard", "Alice", "Bob"],
})


out = df.with_columns(
   pig_latin = language.pig_latinnify("names")
)

或者,您可以 注册一个自定义命名空间,这使您可以编写

out = df.with_columns(
   pig_latin = pl.col("names").language.pig_latinnify()
)

请参阅 example/derive_expression 中的完整示例: https://github.com/pola-rs/pyo3-polars/tree/main/example/derive_expression

2. Polars 的 Pyo3 扩展

请参阅 example 目录中的具体示例。在这里,我们将一个 polars DataFrame 发送到 rust,然后使用 rayon 和 rust 哈希集并行计算 jaccard similarity

运行示例

$ cd example && make install $ venv/bin/python run.py

这将输出

shape: (2, 2)
┌───────────┬───────────────┐
│ list_a    ┆ list_b        │
│ ------           │
│ list[i64] ┆ list[i64]     │
╞═══════════╪═══════════════╡
│ [1, 2, 3][1, 2, ... 8] │
│ [5, 5][5, 1, 1]     │
└───────────┴───────────────┘
shape: (2, 1)
┌─────────┐
│ jaccard │
│ ---     │
│ f64     │
╞═════════╡
│ 0.75    │
│ 0.5     │
└─────────┘

编译发布版

$make install-release

预期内容

这个包提供了一个 PySeries 和一个 PyDataFrame,它们是 SeriesDataFrame 的简单包装。这些包装的优势在于,它们可以通过实现 FromPyObjectIntoPy 来在 python 之间进行转换。

依赖关系

~15–50MB
~782K SLoC