Skip to content
masterclassBuddyTech Buzz5 fresh blogs · 5:00 AM IST

Polars · Function

pl.scan_csv

Lazily scans one or more CSV inputs and returns a LazyFrame. Deferred execution lets Polars optimize filters and column selection before parsing data.

How it works

scan_csv creates a LazyFrame instead of immediately loading rows into a DataFrame. Polars can then optimize downstream filters and column selections, potentially reducing the amount of data parsed and memory used when collect() executes the plan.

Syntax

polars.scan_csv(source, *, has_header=True, separator=',', comment_prefix=None, quote_char='"', skip_rows=0, skip_lines=0, schema=None, schema_overrides=None, infer_schema=True, infer_schema_length=100, infer_schema_files=10, null_values=None, missing_utf8_is_empty_string=False, ignore_errors=False, cache=True, with_column_names=None, n_rows=None, encoding='utf8', missing_columns=None)

Parameters

NameTypeDescription
sourcestr | Path | IO[str] | IO[bytes] | bytes | list[str] | list[Path] | list[IO[str]] | list[IO[bytes]] | list[bytes]Path(s) to a file or file-like object; supported values include paths, bytes, and lists of these sources.
has_headerbool = TrueWhether the first row contains column names.
separatorstr = ','Field delimiter used by the CSV input.
comment_prefixstr | None = NonePrefix identifying comment lines.
quote_charstr | None = '"'Character used to quote fields.
skip_rowsint = 0Number of rows to skip before reading the header or data.
skip_linesint = 0Number of lines to skip before parsing.
schemaSchemaDict | None = NoneComplete column-name-to-data-type mapping; disables schema inference.
schema_overridesSchemaDict | Sequence[PolarsDataType] | None = NoneData types to apply or override during parsing.
infer_schemabool = TrueWhether to infer column data types.
infer_schema_lengthint | None = 100Number of rows used for schema inference.
infer_schema_filesint = 10Number of files used for schema inference in a multi-file scan.

Returns

LazyFrame

Key points

  • The function creates a lazy CSV scan and supports reading one file or multiple files selected by glob patterns.
  • Filters and selected columns can be pushed into the scan plan, reducing unnecessary parsing and memory use.
  • source accepts paths, file-like inputs, bytes, or lists containing those supported source forms.
  • By default, the first CSV row is treated as the header; set has_header=False when the input has no header row.
  • Schema inference is enabled by default, and infer_schema_length controls how many rows are sampled for inference.
  • For multi-file scans, the default inference process considers up to ten files when determining the schema.
  • When scanning inputs with differing columns, the missing-column policy can insert absent columns or raise an error.

Common mistakes

  • Providing a complete schema disables schema inference; every column and its data type must be specified.
  • The source may be a path, file-like object, bytes value, or list of supported sources; choose a source form compatible with the intended input.

Example: Scan and optimize a CSV query

import polars as pl

q = (
    pl.scan_csv("data.csv")
    .filter(pl.col("age") >= 18)
    .select("name", "age")
)
result = q.collect()

Builds a lazy CSV query, applies filtering and projection before execution, then materializes the result.

When to use it

Memory-conscious lazy queries

Apply filters and select only needed columns before calling collect() on large CSV datasets.

Multi-file ingestion

Read partitioned or batch-exported CSV files using a glob pattern as one logical input.

Controlled data typing

Provide schema or schema_overrides when CSV type inference is unreliable or must be deterministic.

Interview questions

QWhat does scan_csv return, and why use it instead of read_csv?

It returns a LazyFrame and postpones CSV parsing until the lazy query is executed. This lets Polars push predicates and projections down to the scan, which can reduce memory overhead.

Follow-up: When would eager reading be preferable? Use read_csv when immediate materialization or simple one-off inspection matters more than lazy-plan optimization.

QWhat kinds of input can source accept?

The source identifies one or more CSV inputs and may be a path, file-like object, bytes value, or supported list of these. A glob pattern can represent multiple files.

Follow-up: How can multiple independent lazy queries be executed together? Build the queries separately and use Polars' collective execution facilities such as collect_all.

QHow do schema and schema_overrides differ?

schema supplies the complete column-to-type mapping and therefore prevents schema inference. schema_overrides changes inferred types for selected columns without requiring a complete schema.

Follow-up: What is the trade-off of supplying a complete schema? It can make types deterministic, but callers must specify every column and type accurately.

  • polars.read_csv
  • polars.LazyFrame.collect
  • polars.LazyFrame.sink_csv
  • polars.collect_all

Source: polars.scan_csv — Polars documentation. Checked 2026-10-15.