1.2.3 Lazy API🔗ℹ

Eager verbs run immediately on a dataframe. The same verbs applied to a lazyframe (from lazy or scan-csv) build a query plan that collect optimises and runs. Here iris-csv is a path to a small CSV.

> (define df-small (~> (read-csv iris-csv) (filter (> (col "sepal_length") 5))))
> (~> df-small (group-by "species") (agg (mean "sepal_width")))

shape: (3, 2)

┌────────────┬─────────────┐

│ species    ┆ sepal_width │

│ ---        ┆ ---         │

│ str        ┆ f64         │

╞════════════╪═════════════╡

│ virginica  ┆ 2.975       │

│ setosa     ┆ 3.7         │

│ versicolor ┆ 2.95        │

└────────────┴─────────────┘

> (define q
    (~> (scan-csv iris-csv)
        (filter (> (col "sepal_length") 5))
        (group-by "species")
        (agg (mean "sepal_width"))))
> (collect q)

shape: (3, 2)

┌────────────┬─────────────┐

│ species    ┆ sepal_width │

│ ---        ┆ ---         │

│ str        ┆ f64         │

╞════════════╪═════════════╡

│ versicolor ┆ 2.95        │

│ setosa     ┆ 3.7         │

│ virginica  ┆ 2.975       │

└────────────┴─────────────┘

explain previews the plan collect would run, after optimisation: the filter has moved into the CSV scan.

> (displayln (explain q))

AGGREGATE[maintain_order: false]

  [col("sepal_width").mean()] BY [col("species")]

  FROM

  simple π 2/2 ["species", "sepal_width"]

    Csv SCAN [/home/root/user/.local/share/racket/9.3/pkgs/polars/scribblings/guide/iris.csv]

    PROJECT 3/5 COLUMNS

    SELECTION: col("sepal_length") > 5.0

    ESTIMATED ROWS: 19

API gap: no schema-only LazyFrame.