phpolars

Reference

Types and values

Data types

Data types are written as py-polars names: 'Int8' … 'Int64', 'UInt8' … 'UInt64', 'Float32', 'Float64', 'Boolean', 'String', 'Binary', 'Date', 'Datetime' (microseconds), 'Datetime(ms, UTC)', 'Duration(us)', 'Time', 'Categorical', 'Null', 'Decimal(10, 2)', 'List(Int64)', 'Array(Int64, 3)', and 'Struct(a: Int64, b: String)', plus 'Int128' and 'UInt128'. Phpolars\DataType has the same names as constants (DataType::Int64), and DataType::datetime('ms', 'UTC') builds the parameterized names.

Values

$df = new DataFrame([
    'n' => [1, null],
    'x' => [1.5, 2.0],
    'ok' => [true, false],
    'when' => [new DateTimeImmutable('2024-05-01 12:30:00'), null],
    'tags' => [['a', 'b'], []],
]);

print_r($df->schema());
var_dump($df->toDicts()[0]);
Array
(
    [n] => Int64
    [x] => Float64
    [ok] => Boolean
    [when] => Datetime(us)
    [tags] => List(String)
)
array(5) {
  ["n"]=>
  int(1)
  ["x"]=>
  float(1.5)
  ["ok"]=>
  bool(true)
  ["when"]=>
  object(DateTimeImmutable)#3 (3) {
    ["date"]=>
    string(26) "2024-05-01 12:30:00.000000"
    ["timezone_type"]=>
    int(3)
    ["timezone"]=>
    string(3) "UTC"
  }
  ["tags"]=>
  array(2) {
    [0]=>
    string(1) "a"
    [1]=>
    string(1) "b"
  }
}
Polars PHP
integer types int (UInt64 values beyond PHP_INT_MAX become float)
Float32, Float64 float
Boolean bool
String, Categorical string
Date, Datetime DateTimeImmutable (naive values in UTC, zoned values in their zone)
Time string, "HH:MM:SS.ffffff"
Duration int in the column’s time unit
Decimal string
List, Array list
Struct associative array

Details of the conversion:

  • Integer precision: Int8 through Int64 and UInt8 through UInt32 fit PHP’s 64-bit int. UInt64, Int128, and UInt128 values beyond PHP_INT_MAX become float, as PHP’s own integer overflow does, so they lose precision above 2^53.
  • Decimal: values come back as strings, such as "1.25" for Decimal(10, 2), so no precision is lost.
  • Time units: Datetime defaults to microseconds. Datetime(ms) and Datetime(ns) keep their unit inside Polars, and PHP’s DateTimeImmutable holds microseconds. A Duration comes back as an integer count of its unit: 1.5 seconds in Duration(ms) is 1500.
  • Time zones: a naive Datetime comes back in UTC. A zoned Datetime, such as Datetime(us, America/New_York), comes back in its zone.
  • Null and NaN: null is a missing value of any type. NaN is a float value, and isNull() is false for it.
  • Lists and structs: a List or Array value is a PHP list, and a Struct value is an associative array keyed by field name.

From PHP, each column gets one inferred type. Integers widen to floats, nulls fit any type, DateTimeInterface values become naive Datetime(us) on their wall-clock time (the zone is not kept; use dt()->replaceTimeZone() to attach one), lists become List, and associative arrays become Struct. Any other mix raises SchemaError; pass a schema to set types.

Errors

Polars errors are thrown as subclasses of Phpolars\PolarsError, named after the py-polars exceptions: ColumnNotFoundError, ComputeError, DuplicateError, InvalidOperationError, NoDataError, OutOfBoundsError, SchemaError, SchemaFieldNotFoundError, ShapeError, and StructFieldNotFoundError, all in Phpolars\Exception. Invalid arguments raise PHP’s ValueError.

use Phpolars\Exception\{ColumnNotFoundError, SchemaError};

$df = new DataFrame(['a' => [1, 2]]);

try {
    $df->select('b');
} catch (ColumnNotFoundError $e) {
    echo get_class($e), ': ', strtok($e->getMessage(), "\n"), "\n";
}
try {
    new DataFrame(['a' => [1, 'two']]);
} catch (SchemaError $e) {
    echo get_class($e), ': ', $e->getMessage(), "\n";
}
echo $e instanceof Phpolars\PolarsError ? "both extend Phpolars\\PolarsError\n" : '';
Phpolars\Exception\ColumnNotFoundError: not found: unable to find column "b"; valid columns: ["a"]
Phpolars\Exception\SchemaError: column 'a' mixes incompatible types; pass a dtype or cast first
both extend Phpolars\PolarsError

From phpstats/phpolars@8487062.