Skip to content

はじめ方

この章では Polars のはじめ方を解説します。ライブラリの基本的な特徴や機能を紹介し、新しいユーザーが最初のインストールからコアな機能を使えるようになるまでの基礎を習得しやすくします。もしあなたが熟練したユーザーであったり、DataFrame に馴染みがあるならば、次のインストールオプションの章にスキップしても問題ありません。

Polars のインストール

pip install polars
cargo add polars -F lazy

# Or Cargo.toml
[dependencies]
polars = { version = "x", features = ["lazy", ...]}

読み込みと書き込み

Polars は一般的なファイル形式(例:csv, json, parquet)、クラウドストレージ(例:S3、Azure Blob、BigQuery)およびデータベース(例:postgres, mysql)の読み書きをサポートしています。以下はディスクへの読み書きの考え方を示します。

DataFrame

import polars as pl
from datetime import datetime

df = pl.DataFrame(
    {
        "integer": [1, 2, 3],
        "date": [
            datetime(2025, 1, 1),
            datetime(2025, 1, 2),
            datetime(2025, 1, 3),
        ],
        "float": [4.0, 5.0, 6.0],
        "string": ["a", "b", "c"],
    }
)

print(df)

DataFrame

use std::fs::File;

use chrono::prelude::*;
use polars::prelude::*;

let mut df: DataFrame = df!(
    "integer" => &[1, 2, 3],
    "date" => &[
            NaiveDate::from_ymd_opt(2025, 1, 1).unwrap().and_hms_opt(0, 0, 0).unwrap(),
            NaiveDate::from_ymd_opt(2025, 1, 2).unwrap().and_hms_opt(0, 0, 0).unwrap(),
            NaiveDate::from_ymd_opt(2025, 1, 3).unwrap().and_hms_opt(0, 0, 0).unwrap(),
    ],
    "float" => &[4.0, 5.0, 6.0],
    "string" => &["a", "b", "c"],
)
.unwrap();
println!("{}", df);

shape: (3, 4)
┌─────────┬─────────────────────┬───────┬────────┐
│ integer ┆ date                ┆ float ┆ string │
│ ---     ┆ ---                 ┆ ---   ┆ ---    │
│ i64     ┆ datetime[μs]        ┆ f64   ┆ str    │
╞═════════╪═════════════════════╪═══════╪════════╡
│ 1       ┆ 2025-01-01 00:00:00 ┆ 4.0   ┆ a      │
│ 2       ┆ 2025-01-02 00:00:00 ┆ 5.0   ┆ b      │
│ 3       ┆ 2025-01-03 00:00:00 ┆ 6.0   ┆ c      │
└─────────┴─────────────────────┴───────┴────────┘

次の例では DataFrame を output.csv という名前の csv ファイルに出力しています。その後に read_csv を用いて再度それを読み込み、確認のために print で表示しています、

read_csv · write_csv

df.write_csv("docs/data/output.csv")
df_csv = pl.read_csv("docs/data/output.csv")
print(df_csv)

CsvReader · CsvWriter · Available on feature csv

let mut file = File::create("docs/data/output.csv").expect("could not create file");
CsvWriter::new(&mut file)
    .include_header(true)
    .with_separator(b',')
    .finish(&mut df)?;
let df_csv = CsvReader::from_path("docs/data/output.csv")?
    .infer_schema(None)
    .has_header(true)
    .finish()?;
println!("{}", df_csv);

shape: (3, 4)
┌─────────┬────────────────────────────┬───────┬────────┐
│ integer ┆ date                       ┆ float ┆ string │
│ ---     ┆ ---                        ┆ ---   ┆ ---    │
│ i64     ┆ str                        ┆ f64   ┆ str    │
╞═════════╪════════════════════════════╪═══════╪════════╡
│ 1       ┆ 2025-01-01T00:00:00.000000 ┆ 4.0   ┆ a      │
│ 2       ┆ 2025-01-02T00:00:00.000000 ┆ 5.0   ┆ b      │
│ 3       ┆ 2025-01-03T00:00:00.000000 ┆ 6.0   ┆ c      │
└─────────┴────────────────────────────┴───────┴────────┘

CSV ファイル形式や他のデータ形式の例をもっと確認したい場合は、ユーザーガイドの IO の章を参照ください。

エクスプレッション

エクスプレッションは Polars のコアな強みです。エクスプレッション は単純なコンセプトを組合せて複雑なクエリを構築することを可能にするモジュール構造を提供します。以下は全てのクエリの構成要素を提供する基本的なコンポーネント(Polars の用語で式と呼ぶ)です: - select - filter - with_columns - group_by

エクスプレッションや式がどのように機能するかをより詳しく学ぶには、ユーザーガイドの および Expressions セクションを参照してください。

選択

カラムを選択するためには2つのことをする必要があります:

  1. データを取得する対象の DataFrame を定義する
  2. 必要なデータを選択する

以下の例では select 時に col('*') と指定しています。アスタリスクは全てのカラムを意味します。

select

df.select(pl.col("*"))

select

let out = df.clone().lazy().select([col("*")]).collect()?;
println!("{}", out);

shape: (5, 4)
┌─────┬──────────┬─────────────────────┬───────┐
│ a   ┆ b        ┆ c                   ┆ d     │
│ --- ┆ ---      ┆ ---                 ┆ ---   │
│ i64 ┆ f64      ┆ datetime[μs]        ┆ f64   │
╞═════╪══════════╪═════════════════════╪═══════╡
│ 0   ┆ 0.755879 ┆ 2025-12-01 00:00:00 ┆ 1.0   │
│ 1   ┆ 0.070227 ┆ 2025-12-02 00:00:00 ┆ 2.0   │
│ 2   ┆ 0.026443 ┆ 2025-12-03 00:00:00 ┆ NaN   │
│ 3   ┆ 0.329713 ┆ 2025-12-04 00:00:00 ┆ -42.0 │
│ 4   ┆ 0.487679 ┆ 2025-12-05 00:00:00 ┆ null  │
└─────┴──────────┴─────────────────────┴───────┘

特定のカラムを指定して取得することもできます。これをするには2つの方法があります。1つは以下のようにカラムの名前を渡す方法です。

select

df.select(pl.col("a", "b"))

select

let out = df.clone().lazy().select([col("a"), col("b")]).collect()?;
println!("{}", out);

shape: (5, 2)
┌─────┬──────────┐
│ a   ┆ b        │
│ --- ┆ ---      │
│ i64 ┆ f64      │
╞═════╪══════════╡
│ 0   ┆ 0.755879 │
│ 1   ┆ 0.070227 │
│ 2   ┆ 0.026443 │
│ 3   ┆ 0.329713 │
│ 4   ┆ 0.487679 │
└─────┴──────────┘

より詳しく学ぶには、ユーザーガイドの基本的な操作カラムの選択を参照してください。

抽出

filter により DataFrame のサブセットを作成することができます。先ほどと同じ DataFrame を使って二つの特定の日付の期間で抽出します。

filter

df.filter(
    pl.col("c").is_between(datetime(2025, 12, 2), datetime(2025, 12, 3)),
)

filter

let start_date = NaiveDate::from_ymd_opt(2025, 12, 2)
    .unwrap()
    .and_hms_opt(0, 0, 0)
    .unwrap();
let end_date = NaiveDate::from_ymd_opt(2025, 12, 3)
    .unwrap()
    .and_hms_opt(0, 0, 0)
    .unwrap();
let out = df
    .clone()
    .lazy()
    .filter(
        col("c")
            .gt_eq(lit(start_date))
            .and(col("c").lt_eq(lit(end_date))),
    )
    .collect()?;
println!("{}", out);

shape: (2, 4)
┌─────┬──────────┬─────────────────────┬─────┐
│ a   ┆ b        ┆ c                   ┆ d   │
│ --- ┆ ---      ┆ ---                 ┆ --- │
│ i64 ┆ f64      ┆ datetime[μs]        ┆ f64 │
╞═════╪══════════╪═════════════════════╪═════╡
│ 1   ┆ 0.070227 ┆ 2025-12-02 00:00:00 ┆ 2.0 │
│ 2   ┆ 0.026443 ┆ 2025-12-03 00:00:00 ┆ NaN │
└─────┴──────────┴─────────────────────┴─────┘

filter を使うことで、複数のカラムを含むより複雑な抽出をすることもできます。

filter

df.filter((pl.col("a") <= 3) & (pl.col("d").is_not_nan()))

filter

let out = df
    .clone()
    .lazy()
    .filter(col("a").lt_eq(3).and(col("d").is_not_null()))
    .collect()?;
println!("{}", out);

shape: (3, 4)
┌─────┬──────────┬─────────────────────┬───────┐
│ a   ┆ b        ┆ c                   ┆ d     │
│ --- ┆ ---      ┆ ---                 ┆ ---   │
│ i64 ┆ f64      ┆ datetime[μs]        ┆ f64   │
╞═════╪══════════╪═════════════════════╪═══════╡
│ 0   ┆ 0.755879 ┆ 2025-12-01 00:00:00 ┆ 1.0   │
│ 1   ┆ 0.070227 ┆ 2025-12-02 00:00:00 ┆ 2.0   │
│ 3   ┆ 0.329713 ┆ 2025-12-04 00:00:00 ┆ -42.0 │
└─────┴──────────┴─────────────────────┴───────┘

カラムの追加

with_columns で分析のための新しいカラムを作成することができます。二つの新しいカラム eb+42 を作ります。まずはカラム b の全ての値の合計を計算し、それをカラム e に保存します。次に b42 を足します。それらの結果を保存する新しいカラム b+42 を作成します。

with_columns

df.with_columns(pl.col("b").sum().alias("e"), (pl.col("b") + 42).alias("b+42"))

with_columns

let out = df
    .clone()
    .lazy()
    .with_columns([
        col("b").sum().alias("e"),
        (col("b") + lit(42)).alias("b+42"),
    ])
    .collect()?;
println!("{}", out);

shape: (5, 6)
┌─────┬──────────┬─────────────────────┬───────┬──────────┬───────────┐
│ a   ┆ b        ┆ c                   ┆ d     ┆ e        ┆ b+42      │
│ --- ┆ ---      ┆ ---                 ┆ ---   ┆ ---      ┆ ---       │
│ i64 ┆ f64      ┆ datetime[μs]        ┆ f64   ┆ f64      ┆ f64       │
╞═════╪══════════╪═════════════════════╪═══════╪══════════╪═══════════╡
│ 0   ┆ 0.755879 ┆ 2025-12-01 00:00:00 ┆ 1.0   ┆ 1.669941 ┆ 42.755879 │
│ 1   ┆ 0.070227 ┆ 2025-12-02 00:00:00 ┆ 2.0   ┆ 1.669941 ┆ 42.070227 │
│ 2   ┆ 0.026443 ┆ 2025-12-03 00:00:00 ┆ NaN   ┆ 1.669941 ┆ 42.026443 │
│ 3   ┆ 0.329713 ┆ 2025-12-04 00:00:00 ┆ -42.0 ┆ 1.669941 ┆ 42.329713 │
│ 4   ┆ 0.487679 ┆ 2025-12-05 00:00:00 ┆ null  ┆ 1.669941 ┆ 42.487679 │
└─────┴──────────┴─────────────────────┴───────┴──────────┴───────────┘

グループ化

グループ化の機能で新しい DataFrame を作成します。この新しい DataFrame はグループ分けしたい複数の「グループ」を持ちます。

DataFrame

df2 = pl.DataFrame(
    {
        "x": range(8),
        "y": ["A", "A", "A", "B", "B", "C", "X", "X"],
    }
)

DataFrame

let df2: DataFrame = df!("x" => 0..8,
    "y"=> &["A", "A", "A", "B", "B", "C", "X", "X"],
)
.expect("should not fail");
println!("{}", df2);

shape: (8, 2)
┌─────┬─────┐
│ x   ┆ y   │
│ --- ┆ --- │
│ i64 ┆ str │
╞═════╪═════╡
│ 0   ┆ A   │
│ 1   ┆ A   │
│ 2   ┆ A   │
│ 3   ┆ B   │
│ 4   ┆ B   │
│ 5   ┆ C   │
│ 6   ┆ X   │
│ 7   ┆ X   │
└─────┴─────┘

group_by

df2.group_by("y", maintain_order=True).len()

group_by

let out = df2.clone().lazy().group_by(["y"]).agg([len()]).collect()?;
println!("{}", out);

shape: (4, 2)
┌─────┬─────┐
│ y   ┆ len │
│ --- ┆ --- │
│ str ┆ u32 │
╞═════╪═════╡
│ A   ┆ 3   │
│ B   ┆ 2   │
│ C   ┆ 1   │
│ X   ┆ 2   │
└─────┴─────┘

group_by

df2.group_by("y", maintain_order=True).agg(
    pl.col("*").count().alias("count"),
    pl.col("*").sum().alias("sum"),
)

group_by

let out = df2
    .clone()
    .lazy()
    .group_by(["y"])
    .agg([col("*").count().alias("count"), col("*").sum().alias("sum")])
    .collect()?;
println!("{}", out);

shape: (4, 3)
┌─────┬───────┬─────┐
│ y   ┆ count ┆ sum │
│ --- ┆ ---   ┆ --- │
│ str ┆ u32   ┆ i64 │
╞═════╪═══════╪═════╡
│ A   ┆ 3     ┆ 3   │
│ B   ┆ 2     ┆ 7   │
│ C   ┆ 1     ┆ 5   │
│ X   ┆ 2     ┆ 13  │
└─────┴───────┴─────┘

組み合わせ

以下は必要な DataFrame を作成するために操作を組み合わせる例です。

select · with_columns

df_x = df.with_columns((pl.col("a") * pl.col("b")).alias("a * b")).select(
    pl.all().exclude(["c", "d"])
)

print(df_x)

select · with_columns

let out = df
    .clone()
    .lazy()
    .with_columns([(col("a") * col("b")).alias("a * b")])
    .select([col("*").exclude(["c", "d"])])
    .collect()?;
println!("{}", out);

shape: (5, 3)
┌─────┬──────────┬──────────┐
│ a   ┆ b        ┆ a * b    │
│ --- ┆ ---      ┆ ---      │
│ i64 ┆ f64      ┆ f64      │
╞═════╪══════════╪══════════╡
│ 0   ┆ 0.755879 ┆ 0.0      │
│ 1   ┆ 0.070227 ┆ 0.070227 │
│ 2   ┆ 0.026443 ┆ 0.052887 │
│ 3   ┆ 0.329713 ┆ 0.989139 │
│ 4   ┆ 0.487679 ┆ 1.950716 │
└─────┴──────────┴──────────┘

select · with_columns

df_y = df.with_columns((pl.col("a") * pl.col("b")).alias("a * b")).select(
    pl.all().exclude("d")
)

print(df_y)

select · with_columns

let out = df
    .clone()
    .lazy()
    .with_columns([(col("a") * col("b")).alias("a * b")])
    .select([col("*").exclude(["d"])])
    .collect()?;
println!("{}", out);

shape: (5, 4)
┌─────┬──────────┬─────────────────────┬──────────┐
│ a   ┆ b        ┆ c                   ┆ a * b    │
│ --- ┆ ---      ┆ ---                 ┆ ---      │
│ i64 ┆ f64      ┆ datetime[μs]        ┆ f64      │
╞═════╪══════════╪═════════════════════╪══════════╡
│ 0   ┆ 0.755879 ┆ 2025-12-01 00:00:00 ┆ 0.0      │
│ 1   ┆ 0.070227 ┆ 2025-12-02 00:00:00 ┆ 0.070227 │
│ 2   ┆ 0.026443 ┆ 2025-12-03 00:00:00 ┆ 0.052887 │
│ 3   ┆ 0.329713 ┆ 2025-12-04 00:00:00 ┆ 0.989139 │
│ 4   ┆ 0.487679 ┆ 2025-12-05 00:00:00 ┆ 1.950716 │
└─────┴──────────┴─────────────────────┴──────────┘

DataFrame を組み合わせる

ユースケースに基づいて DataFrame を組み合わせる方法が2つあります:join と concat です。

Join

Polars はすべての種類の join(例: left, right, inner, outer)をサポートします。2つの DataFramejoin で1つの DataFrame にする方法を詳しく見てみましょう。2つの DataFrame はどちらも「id」のようなカラムを持ちます:ax です。この例ではこれらのカラムを使って DataFramejoin します。

join

df = pl.DataFrame(
    {
        "a": range(8),
        "b": np.random.rand(8),
        "d": [1, 2.0, float("nan"), float("nan"), 0, -5, -42, None],
    }
)

df2 = pl.DataFrame(
    {
        "x": range(8),
        "y": ["A", "A", "A", "B", "B", "C", "X", "X"],
    }
)
joined = df.join(df2, left_on="a", right_on="x")
print(joined)

join

use rand::Rng;
let mut rng = rand::thread_rng();

let df: DataFrame = df!(
    "a" => 0..8,
    "b"=> (0..8).map(|_| rng.gen::<f64>()).collect::<Vec<f64>>(),
    "d"=> [Some(1.0), Some(2.0), None, None, Some(0.0), Some(-5.0), Some(-42.), None]
)
.unwrap();
let df2: DataFrame = df!(
    "x" => 0..8,
    "y"=> &["A", "A", "A", "B", "B", "C", "X", "X"],
)
.unwrap();
let joined = df.join(&df2, ["a"], ["x"], JoinType::Left.into())?;
println!("{}", joined);

shape: (8, 4)
┌─────┬──────────┬───────┬─────┐
│ a   ┆ b        ┆ d     ┆ y   │
│ --- ┆ ---      ┆ ---   ┆ --- │
│ i64 ┆ f64      ┆ f64   ┆ str │
╞═════╪══════════╪═══════╪═════╡
│ 0   ┆ 0.671125 ┆ 1.0   ┆ A   │
│ 1   ┆ 0.912367 ┆ 2.0   ┆ A   │
│ 2   ┆ 0.103817 ┆ NaN   ┆ A   │
│ 3   ┆ 0.321364 ┆ NaN   ┆ B   │
│ 4   ┆ 0.562468 ┆ 0.0   ┆ B   │
│ 5   ┆ 0.520004 ┆ -5.0  ┆ C   │
│ 6   ┆ 0.25765  ┆ -42.0 ┆ X   │
│ 7   ┆ 0.834989 ┆ null  ┆ X   │
└─────┴──────────┴───────┴─────┘

他の種類の結合の例を見たい場合は、ユーザーガイドの Transformations section を参照してください。

Concat

2つの DataFrame を「連結」することもできます。垂直方向の連結は DataFrame を長くします。水平方向の連結は DataFrame の幅を広げます。以下は2つの DataFrame を水平方向に連結した結果です。

hstack

stacked = df.hstack(df2)
print(stacked)

hstack

let stacked = df.hstack(df2.get_columns())?;
println!("{}", stacked);

shape: (8, 5)
┌─────┬──────────┬───────┬─────┬─────┐
│ a   ┆ b        ┆ d     ┆ x   ┆ y   │
│ --- ┆ ---      ┆ ---   ┆ --- ┆ --- │
│ i64 ┆ f64      ┆ f64   ┆ i64 ┆ str │
╞═════╪══════════╪═══════╪═════╪═════╡
│ 0   ┆ 0.671125 ┆ 1.0   ┆ 0   ┆ A   │
│ 1   ┆ 0.912367 ┆ 2.0   ┆ 1   ┆ A   │
│ 2   ┆ 0.103817 ┆ NaN   ┆ 2   ┆ A   │
│ 3   ┆ 0.321364 ┆ NaN   ┆ 3   ┆ B   │
│ 4   ┆ 0.562468 ┆ 0.0   ┆ 4   ┆ B   │
│ 5   ┆ 0.520004 ┆ -5.0  ┆ 5   ┆ C   │
│ 6   ┆ 0.25765  ┆ -42.0 ┆ 6   ┆ X   │
│ 7   ┆ 0.834989 ┆ null  ┆ 7   ┆ X   │
└─────┴──────────┴───────┴─────┴─────┘