Skip to content

関数(Functions)

Polars 式には多くの組み込み関数があります。これらを使用することで、ユーザー定義関数を必要とせずに複雑なクエリを作成できます。ここで全てを説明するには多すぎますが、より一般的な使用例のいくつかをカバーします。すべての関数を見たい場合は、プログラミング言語のAPIリファレンスを参照してください。

以下の例では、次のDataFrameを使用します:

DataFrame

df = pl.DataFrame(
    {
        "nrs": [1, 2, 3, None, 5],
        "names": ["foo", "ham", "spam", "egg", "spam"],
        "random": np.random.rand(5),
        "groups": ["A", "A", "B", "C", "B"],
    }
)
print(df)

DataFrame

use rand::{thread_rng, Rng};

let mut arr = [0f64; 5];
thread_rng().fill(&mut arr);

let df = df! (
    "nrs" => &[Some(1), Some(2), Some(3), None, Some(5)],
    "names" => &["foo", "ham", "spam", "egg", "spam"],
    "random" => &arr,
    "groups" => &["A", "A", "B", "C", "B"],
)?;

println!("{}", &df);

shape: (5, 4)
┌──────┬───────┬──────────┬────────┐
│ nrs  ┆ names ┆ random   ┆ groups │
│ ---  ┆ ---   ┆ ---      ┆ ---    │
│ i64  ┆ str   ┆ f64      ┆ str    │
╞══════╪═══════╪══════════╪════════╡
│ 1    ┆ foo   ┆ 0.154163 ┆ A      │
│ 2    ┆ ham   ┆ 0.74005  ┆ A      │
│ 3    ┆ spam  ┆ 0.263315 ┆ B      │
│ null ┆ egg   ┆ 0.533739 ┆ C      │
│ 5    ┆ spam  ┆ 0.014575 ┆ B      │
└──────┴───────┴──────────┴────────┘

カラム名付け

デフォルトでは、式を実行すると元のカラムと同じ名前が保持されます。以下の例では、nrsカラムに対して式を実行しています。出力DataFrameには依然として同じ名前があります。

df_samename = df.select(pl.col("nrs") + 5)
print(df_samename)
let df_samename = df.clone().lazy().select([col("nrs") + lit(5)]).collect()?;
println!("{}", &df_samename);
shape: (5, 1)
┌──────┐
│ nrs  │
│ ---  │
│ i64  │
╞══════╡
│ 6    │
│ 7    │
│ 8    │
│ null │
│ 10   │
└──────┘

同じカラムを式の中で複数回使用する場合、出力カラムが重複してしまい問題が発生することがあります。例えば、以下のクエリは失敗します。

try:
    df_samename2 = df.select(pl.col("nrs") + 5, pl.col("nrs") - 5)
    print(df_samename2)
except Exception as e:
    print(e)
let df_samename2 = df
    .clone()
    .lazy()
    .select([col("nrs") + lit(5), col("nrs") - lit(5)])
    .collect();
match df_samename2 {
    Ok(df) => println!("{}", &df),
    Err(e) => println!("{:?}", &e),
};
the name: 'nrs' is duplicate

It's possible that multiple expressions are returning the same default column name. If this is the case, try renaming the columns with `.alias("new_name")` to avoid duplicate column names.

式の出力名を変更するには、alias関数を使用します。

alias

df_alias = df.select(
    (pl.col("nrs") + 5).alias("nrs + 5"),
    (pl.col("nrs") - 5).alias("nrs - 5"),
)
print(df_alias)

alias

let df_alias = df
    .clone()
    .lazy()
    .select([
        (col("nrs") + lit(5)).alias("nrs + 5"),
        (col("nrs") - lit(5)).alias("nrs - 5"),
    ])
    .collect()?;
println!("{}", &df_alias);

shape: (5, 2)
┌─────────┬─────────┐
│ nrs + 5 ┆ nrs - 5 │
│ ---     ┆ ---     │
│ i64     ┆ i64     │
╞═════════╪═════════╡
│ 6       ┆ -4      │
│ 7       ┆ -3      │
│ 8       ┆ -2      │
│ null    ┆ null    │
│ 10      ┆ 0       │
└─────────┴─────────┘

例えば、all()col(*)を使用する場合の複数のカラムに対して、name.mapなどのマッピング関数を適用して元のカラム名を変更することができます。サフィックス(name.suffix())やプレフィックス(name.prefix())を追加する場合も、これらは組み込まれています。

name.prefix name.suffix name.map

一意の値のカウント

Polarsでは、一意の値を数えるために2つの方法があります:正確な方法と近似法です。近似法は、HyperLogLog++アルゴリズムを使用して基数を近似し、近似で十分な非常に大きなデータセットで特に役立ちます。

n_unique · approx_n_unique

df_alias = df.select(
    pl.col("names").n_unique().alias("unique"),
    pl.approx_n_unique("names").alias("unique_approx"),
)
print(df_alias)

n_unique · approx_n_unique

let df_alias = df
    .clone()
    .lazy()
    .select([
        col("names").n_unique().alias("unique"),
        // Following query shows there isn't anything in Rust API
        // https://docs.rs/polars/latest/polars/?search=approx_n_unique
        // col("names").approx_n_unique().alias("unique_approx"),
    ])
    .collect()?;
println!("{}", &df_alias);

shape: (1, 2)
┌────────┬───────────────┐
│ unique ┆ unique_approx │
│ ---    ┆ ---           │
│ u32    ┆ u32           │
╞════════╪═══════════════╡
│ 4      ┆ 4             │
└────────┴───────────────┘

条件式

Polarsは、whenthenotherwise構文で if-else のような条件を式にサポートしています。述語はwhen句に置かれ、これがtrueと評価されるとthen式が適用され、そうでない場合はotherwise式が適用されます(行ごとに)。

when

df_conditional = df.select(
    pl.col("nrs"),
    pl.when(pl.col("nrs") > 2)
    .then(pl.lit(True))
    .otherwise(pl.lit(False))
    .alias("conditional"),
)
print(df_conditional)

when

let df_conditional = df
    .clone()
    .lazy()
    .select([
        col("nrs"),
        when(col("nrs").gt(2))
            .then(lit(true))
            .otherwise(lit(false))
            .alias("conditional"),
    ])
    .collect()?;
println!("{}", &df_conditional);

shape: (5, 2)
┌──────┬─────────────┐
│ nrs  ┆ conditional │
│ ---  ┆ ---         │
│ i64  ┆ bool        │
╞══════╪═════════════╡
│ 1    ┆ false       │
│ 2    ┆ false       │
│ 3    ┆ true        │
│ null ┆ false       │
│ 5    ┆ true        │
└──────┴─────────────┘