phpolars

Reference

DataFrame and LazyFrame

DataFrame holds data in memory and runs each operation immediately. LazyFrame records operations and runs them, optimized, on collect(). Both have the same verbs; a DataFrame builds each verb on a lazy query and collects it, as py-polars does.

Creating data frames

$df = new DataFrame(['a' => [1, 2], 'b' => ['x', 'y']]);          // columns
$df = new DataFrame([['a' => 1, 'b' => 'x'], ['a' => 2, 'b' => 'y']]);  // rows
$df = DataFrame::fromRows([[1, 'x'], [2, 'y']], schema: ['a' => 'Int32', 'b' => 'String']);
$df = new DataFrame(['a' => new Series('a', [1, 2])]);
$df = read_csv('data.csv');
$lf = $df->lazy();      // or scan_csv(), scan_parquet(), ...

A schema argument names columns and sets their types.

Joins

join() takes on, or leftOn and rightOn, and how: inner, left, right, full, semi, anti, or cross. suffix names clashing right-hand columns, coalesce merges key columns, nullsEqual lets null keys match, and maintainOrder (none, left, right, left_right, right_left) fixes the row order.

$sales = read_csv('sales.csv')->select('id', 'store', 'units')->head(6);
$stores = read_csv('stores.csv')->filter(col('store')->ne('S2'));

echo $sales->join($stores, on: 'store', how: 'left', maintainOrder: 'left'), "\n";
echo $sales->join($stores, on: 'store', how: 'anti'), "\n";
echo $stores->rename(['store' => 'shop'])->join($sales, leftOn: 'shop', rightOn: 'store', how: 'inner')->height(), " matched rows\n";
shape: (6, 5)
┌─────┬───────┬───────┬──────────┬────────┐
│ id  ┆ store ┆ units ┆ city     ┆ region │
│ --- ┆ ---   ┆ ---   ┆ ---      ┆ ---    │
│ i64 ┆ str   ┆ i64   ┆ str      ┆ str    │
╞═════╪═══════╪═══════╪══════════╪════════╡
│ 1   ┆ S4    ┆ 10    ┆ Portland ┆ West   │
│ 2   ┆ S4    ┆ 0     ┆ Portland ┆ West   │
│ 3   ┆ S2    ┆ 2     ┆ null     ┆ null   │
│ 4   ┆ S3    ┆ 12    ┆ Atlanta  ┆ East   │
│ 5   ┆ S4    ┆ 1     ┆ Portland ┆ West   │
│ 6   ┆ S2    ┆ 6     ┆ null     ┆ null   │
└─────┴───────┴───────┴──────────┴────────┘
shape: (2, 3)
┌─────┬───────┬───────┐
│ id  ┆ store ┆ units │
│ --- ┆ ---   ┆ ---   │
│ i64 ┆ str   ┆ i64   │
╞═════╪═══════╪═══════╡
│ 3   ┆ S2    ┆ 2     │
│ 6   ┆ S2    ┆ 6     │
└─────┴───────┴───────┘
4 matched rows

Iterating over groups

A GroupBy works with foreach, as py-polars’ does. The key is a list of the group’s key values, and the value is the group’s rows as a DataFrame:

foreach ($sales->groupBy('store', maintainOrder: true) as $key => $rows) {
    echo $key[0], ': ', $rows->height(), "\n";
}

Time series

groupByDynamic() groups rows into fixed time windows, and rolling() gives each row a window that ends at it. joinAsof() matches each row to the nearest earlier (or later, or nearest) row of another data frame, optionally within by groups and a tolerance. Durations are py-polars strings such as '1d', '2h30m', '1w', and '1mo'. Expressions add the rolling*By() family and ewmMean(). The functions date_range() and datetime_range() build calendars.

$daily = read_csv('sales.csv', tryParseDates: true)
    ->groupBy('date')->agg(col('units')->sum())
    ->sort('date');

// Weeks starting on Monday.
echo $daily->groupByDynamic('date', every: '1w')->agg(col('units')->sum()->alias('week_units'))->head(3), "\n";

// The seven days ending at each row.
echo $daily->withColumns(col('units')->rollingSumBy('date', '7d')->alias('last_7d'))->head(4), "\n";

// The list price in force on each day.
$prices = (new DataFrame(['from' => [new DateTimeImmutable('2024-01-01'), new DateTimeImmutable('2024-01-05')], 'list_price' => [5.0, 5.5]]))
    ->cast(['from' => 'Date']);
echo $daily->head(4)->joinAsof($prices, leftOn: 'date', rightOn: 'from');
shape: (3, 2)
┌────────────┬────────────┐
│ date       ┆ week_units │
│ ---        ┆ ---        │
│ date       ┆ i64        │
╞════════════╪════════════╡
│ 2024-01-01 ┆ 109        │
│ 2024-01-08 ┆ 30         │
│ 2024-01-15 ┆ 71         │
└────────────┴────────────┘
shape: (4, 3)
┌────────────┬───────┬─────────┐
│ date       ┆ units ┆ last_7d │
│ ---        ┆ ---   ┆ ---     │
│ date       ┆ i64   ┆ i64     │
╞════════════╪═══════╪═════════╡
│ 2024-01-01 ┆ 15    ┆ 15      │
│ 2024-01-02 ┆ 23    ┆ 38      │
│ 2024-01-03 ┆ 6     ┆ 44      │
│ 2024-01-04 ┆ 19    ┆ 63      │
└────────────┴───────┴─────────┘
shape: (4, 4)
┌────────────┬───────┬────────────┬────────────┐
│ date       ┆ units ┆ from       ┆ list_price │
│ ---        ┆ ---   ┆ ---        ┆ ---        │
│ date       ┆ i64   ┆ date       ┆ f64        │
╞════════════╪═══════╪════════════╪════════════╡
│ 2024-01-01 ┆ 15    ┆ 2024-01-01 ┆ 5.0        │
│ 2024-01-02 ┆ 23    ┆ 2024-01-01 ┆ 5.0        │
│ 2024-01-03 ┆ 6     ┆ 2024-01-01 ┆ 5.0        │
│ 2024-01-04 ┆ 19    ┆ 2024-01-01 ┆ 5.0        │
└────────────┴───────┴────────────┴────────────┘

Reshaping

$wide = new DataFrame(['id' => [1, 2], 'q1' => [10, 20], 'q2' => [11, 21]]);

$long = $wide->unpivot(index: 'id', variableName: 'quarter', valueName: 'sales');
echo $long, "\n";
echo $long->pivot('quarter', index: 'id', values: 'sales'), "\n";
echo concat([$wide, new DataFrame(['id' => [3], 'q1' => [30], 'q2' => [31]])]), "\n";
echo $wide->describe();
shape: (4, 3)
┌─────┬─────────┬───────┐
│ id  ┆ quarter ┆ sales │
│ --- ┆ ---     ┆ ---   │
│ i64 ┆ str     ┆ i64   │
╞═════╪═════════╪═══════╡
│ 1   ┆ q1      ┆ 10    │
│ 2   ┆ q1      ┆ 20    │
│ 1   ┆ q2      ┆ 11    │
│ 2   ┆ q2      ┆ 21    │
└─────┴─────────┴───────┘
shape: (2, 3)
┌─────┬─────┬─────┐
│ id  ┆ q1  ┆ q2  │
│ --- ┆ --- ┆ --- │
│ i64 ┆ i64 ┆ i64 │
╞═════╪═════╪═════╡
│ 1   ┆ 10  ┆ 11  │
│ 2   ┆ 20  ┆ 21  │
└─────┴─────┴─────┘
shape: (3, 3)
┌─────┬─────┬─────┐
│ id  ┆ q1  ┆ q2  │
│ --- ┆ --- ┆ --- │
│ i64 ┆ i64 ┆ i64 │
╞═════╪═════╪═════╡
│ 1   ┆ 10  ┆ 11  │
│ 2   ┆ 20  ┆ 21  │
│ 3   ┆ 30  ┆ 31  │
└─────┴─────┴─────┘
shape: (9, 4)
┌────────────┬──────────┬──────────┬──────────┐
│ statistic  ┆ id       ┆ q1       ┆ q2       │
│ ---        ┆ ---      ┆ ---      ┆ ---      │
│ str        ┆ f64      ┆ f64      ┆ f64      │
╞════════════╪══════════╪══════════╪══════════╡
│ count      ┆ 2.0      ┆ 2.0      ┆ 2.0      │
│ null_count ┆ 0.0      ┆ 0.0      ┆ 0.0      │
│ mean       ┆ 1.5      ┆ 15.0     ┆ 16.0     │
│ std        ┆ 0.707107 ┆ 7.071068 ┆ 7.071068 │
│ min        ┆ 1.0      ┆ 10.0     ┆ 11.0     │
│ 25%        ┆ 1.0      ┆ 10.0     ┆ 11.0     │
│ 50%        ┆ 2.0      ┆ 20.0     ┆ 21.0     │
│ 75%        ┆ 2.0      ┆ 20.0     ┆ 21.0     │
│ max        ┆ 2.0      ┆ 20.0     ┆ 21.0     │
└────────────┴──────────┴──────────┴──────────┘

Getting values out

Method Returns
toDicts() list of rows, each ['column' => value]
rows() list of rows, each a list of values
row($i, named: true) one row
toDict() ['column' => Series]; toDict(asSeries: false) gives lists
getColumn('a') a Series
item(), item($row, $column) one value
schema(), dtypes(), columns(), shape() structure

Methods

Phpolars\DataFrame

__toString(): string
approxNUnique(): Phpolars\DataFrame
bottomK(int $k, mixed $by, mixed $reverse = null): Phpolars\DataFrame
cast(mixed $dtypes, ?bool $strict = null): Phpolars\DataFrame
clear(?int $n = null): Phpolars\DataFrame
clone(): Phpolars\DataFrame
collectSchema(): array
columns(): array
corr(): Phpolars\DataFrame
count(): Phpolars\DataFrame
describe(?array $percentiles = null): Phpolars\DataFrame
drop(mixed ...$columns): Phpolars\DataFrame
dropNans(mixed $subset = null): Phpolars\DataFrame
dropNulls(mixed $subset = null): Phpolars\DataFrame
dtypes(): array
equals(Phpolars\DataFrame $other, ?bool $nullEqual = null): bool
estimatedSize(): int
explode(mixed ...$columns): Phpolars\DataFrame
extend(Phpolars\DataFrame $other): Phpolars\DataFrame
fillNan(mixed $value): Phpolars\DataFrame
fillNull(mixed $value = null, ?string $strategy = null, ?int $limit = null): Phpolars\DataFrame
filter(mixed ...$predicates): Phpolars\DataFrame
first(): Phpolars\DataFrame
gather(mixed $indices): Phpolars\DataFrame
gatherEvery(int $n, ?int $offset = null): Phpolars\DataFrame
getColumn(string $name): Phpolars\Series
getColumnIndex(string $name): int
getColumns(): array
glimpse(?int $maxItemsPerColumn = null): string
groupBy(mixed $by, ?bool $maintainOrder = null): Phpolars\GroupBy
groupByDynamic(mixed $indexColumn, string $every, ?string $period = null, ?string $offset = null, ?bool $includeBoundaries = null, ?string $closed = null, ?string $label = null, mixed $groupBy = null, ?string $startBy = null): Phpolars\GroupBy
head(?int $n = null): Phpolars\DataFrame
height(): int
hstack(mixed $columns): Phpolars\DataFrame
insertColumn(int $index, Phpolars\Series $column): Phpolars\DataFrame
interpolate(): Phpolars\DataFrame
isDuplicated(): Phpolars\Series
isEmpty(): bool
isUnique(): Phpolars\Series
item(?int $row = null, mixed $column = null): mixed
iterColumns(): array
iterRows(?bool $named = null): array
iterSlices(?int $nRows = null): array
join(mixed $other, mixed $on = null, ?string $how = null, mixed $leftOn = null, mixed $rightOn = null, ?string $suffix = null, ?bool $coalesce = null, ?string $maintainOrder = null, ?bool $nullsEqual = null): Phpolars\DataFrame
joinAsof(mixed $other, mixed $on = null, mixed $leftOn = null, mixed $rightOn = null, mixed $by = null, mixed $byLeft = null, mixed $byRight = null, ?string $strategy = null, ?string $suffix = null, mixed $tolerance = null, ?bool $allowExactMatches = null, ?bool $checkSortedness = null, ?bool $coalesce = null): Phpolars\DataFrame
joinWhere(mixed $other, mixed ...$predicates): Phpolars\DataFrame
last(): Phpolars\DataFrame
lazy(): Phpolars\LazyFrame
limit(?int $n = null): Phpolars\DataFrame
mapRows(mixed $function): Phpolars\DataFrame
max(): Phpolars\DataFrame
maxHorizontal(): Phpolars\Series
mean(): Phpolars\DataFrame
meanHorizontal(?bool $ignoreNulls = null): Phpolars\Series
median(): Phpolars\DataFrame
melt(mixed $idVars = null, mixed $valueVars = null, ?string $variableName = null, ?string $valueName = null): Phpolars\DataFrame
mergeSorted(mixed $other, mixed $key, ?bool $maintainOrder = null): Phpolars\DataFrame
min(): Phpolars\DataFrame
minHorizontal(): Phpolars\Series
nChunks(): int
nUnique(): Phpolars\DataFrame
nullCount(): Phpolars\DataFrame
partitionBy(mixed $by, ?bool $maintainOrder = null, ?bool $includeKey = null, ?bool $asDict = null): array
pivot(mixed $on, mixed $index = null, mixed $values = null, mixed $aggregateFunction = null, ?bool $sortColumns = null, ?string $separator = null, ?bool $maintainOrder = null): Phpolars\DataFrame
product(): Phpolars\DataFrame
quantile(float $quantile, ?string $interpolation = null): Phpolars\DataFrame
rechunk(): Phpolars\DataFrame
remove(mixed ...$predicates): Phpolars\DataFrame
rename(array $mapping, ?bool $strict = null): Phpolars\DataFrame
replaceColumn(int $index, Phpolars\Series $column): Phpolars\DataFrame
reverse(): Phpolars\DataFrame
rolling(mixed $indexColumn, string $period, ?string $offset = null, ?string $closed = null, mixed $groupBy = null): Phpolars\GroupBy
row(int $index, ?bool $named = null): mixed
rows(?bool $named = null): array
rowsByKey(string $key, ?bool $named = null, ?bool $includeKey = null, ?bool $unique = null): array
sample(?int $n = null, ?float $fraction = null, ?bool $withReplacement = null, ?bool $shuffle = null, ?int $seed = null): Phpolars\DataFrame
schema(): array
select(mixed ...$exprs): Phpolars\DataFrame
selectSeq(mixed ...$exprs): Phpolars\DataFrame
shape(): array
shift(?int $n = null, mixed $fillValue = null): Phpolars\DataFrame
shrinkToFit(): Phpolars\DataFrame
slice(int $offset, ?int $length = null): Phpolars\DataFrame
sort(mixed $by, mixed $descending = null, mixed $nullsLast = null, ?bool $maintainOrder = null): Phpolars\DataFrame
sql(string $query, ?string $tableName = null): Phpolars\DataFrame
static fromDict(array $data, ?array $schema = null): Phpolars\DataFrame
static fromDicts(array $data, ?array $schema = null): Phpolars\DataFrame
static fromPhibble(mixed $table): Phpolars\DataFrame
static fromRows(array $data, ?array $schema = null): Phpolars\DataFrame
std(?int $ddof = null): Phpolars\DataFrame
sum(): Phpolars\DataFrame
sumHorizontal(?bool $ignoreNulls = null): Phpolars\Series
tail(?int $n = null): Phpolars\DataFrame
toColumns(): array
toDict(?bool $asSeries = null): array
toDicts(): array
toDummies(mixed $columns = null, ?string $separator = null, ?bool $dropFirst = null, ?bool $dropNulls = null): Phpolars\DataFrame
toPhibble(): mixed
toSeries(?int $index = null): Phpolars\Series
toStruct(?string $name = null): Phpolars\Series
topK(int $k, mixed $by, mixed $reverse = null): Phpolars\DataFrame
transpose(?bool $includeHeader = null, ?string $headerName = null, mixed $columnNames = null): Phpolars\DataFrame
unique(mixed $subset = null, ?string $keep = null, ?bool $maintainOrder = null): Phpolars\DataFrame
unnest(mixed ...$columns): Phpolars\DataFrame
unpivot(mixed $on = null, mixed $index = null, ?string $variableName = null, ?string $valueName = null): Phpolars\DataFrame
update(mixed $other, mixed $on = null, ?string $how = null, mixed $leftOn = null, mixed $rightOn = null, ?bool $includeNulls = null, ?string $maintainOrder = null): Phpolars\DataFrame
upsample(string $timeColumn, string $every, mixed $groupBy = null, ?bool $maintainOrder = null): Phpolars\DataFrame
var(?int $ddof = null): Phpolars\DataFrame
vstack(Phpolars\DataFrame $other): Phpolars\DataFrame
width(): int
withColumns(mixed ...$exprs): Phpolars\DataFrame
withColumnsSeq(mixed ...$exprs): Phpolars\DataFrame
withRowIndex(?string $name = null, ?int $offset = null): Phpolars\DataFrame
writeCsv(string $file, ?bool $includeHeader = null, ?string $separator = null, ?string $nullValue = null, ?string $quoteChar = null, ?string $dateFormat = null, ?string $datetimeFormat = null, ?string $timeFormat = null, ?bool $floatScientific = null, ?int $floatPrecision = null, ?bool $decimalComma = null, ?string $lineTerminator = null, ?string $quoteStyle = null, ?bool $includeBom = null): void
writeDatabase(string $tableName, mixed $connection, ?string $ifTableExists = null): int
writeIpc(string $file): void
writeIpcStream(string $file): void
writeJson(string $file): void
writeNdjson(string $file): void
writeParquet(string $file, ?string $compression = null, ?int $compressionLevel = null, ?bool $statistics = null, ?int $rowGroupSize = null): void

Phpolars\LazyFrame

__toString(): string
approxNUnique(): Phpolars\LazyFrame
bottomK(int $k, mixed $by, mixed $reverse = null): Phpolars\LazyFrame
cache(): Phpolars\LazyFrame
cast(mixed $dtypes, ?bool $strict = null): Phpolars\LazyFrame
clear(?int $n = null): Phpolars\LazyFrame
clone(): Phpolars\LazyFrame
collect(?string $engine = null): Phpolars\DataFrame
collectSchema(): array
columns(): array
count(): Phpolars\LazyFrame
describe(?array $percentiles = null): Phpolars\DataFrame
drop(mixed ...$columns): Phpolars\LazyFrame
dropNans(mixed $subset = null): Phpolars\LazyFrame
dropNulls(mixed $subset = null): Phpolars\LazyFrame
dtypes(): array
explain(?bool $optimized = null): string
explode(mixed ...$columns): Phpolars\LazyFrame
fetch(?int $n = null): Phpolars\DataFrame
fillNan(mixed $value): Phpolars\LazyFrame
fillNull(mixed $value = null, ?string $strategy = null, ?int $limit = null): Phpolars\LazyFrame
filter(mixed ...$predicates): Phpolars\LazyFrame
first(): Phpolars\LazyFrame
gather(mixed $indices): Phpolars\LazyFrame
gatherEvery(int $n, ?int $offset = null): Phpolars\LazyFrame
groupBy(mixed $by, ?bool $maintainOrder = null): Phpolars\LazyGroupBy
groupByDynamic(mixed $indexColumn, string $every, ?string $period = null, ?string $offset = null, ?bool $includeBoundaries = null, ?string $closed = null, ?string $label = null, mixed $groupBy = null, ?string $startBy = null): Phpolars\LazyGroupBy
head(?int $n = null): Phpolars\LazyFrame
interpolate(): Phpolars\LazyFrame
join(mixed $other, mixed $on = null, ?string $how = null, mixed $leftOn = null, mixed $rightOn = null, ?string $suffix = null, ?bool $coalesce = null, ?string $maintainOrder = null, ?bool $nullsEqual = null): Phpolars\LazyFrame
joinAsof(mixed $other, mixed $on = null, mixed $leftOn = null, mixed $rightOn = null, mixed $by = null, mixed $byLeft = null, mixed $byRight = null, ?string $strategy = null, ?string $suffix = null, mixed $tolerance = null, ?bool $allowExactMatches = null, ?bool $checkSortedness = null, ?bool $coalesce = null): Phpolars\LazyFrame
joinWhere(mixed $other, mixed ...$predicates): Phpolars\LazyFrame
last(): Phpolars\LazyFrame
lazy(): Phpolars\LazyFrame
limit(?int $n = null): Phpolars\LazyFrame
max(): Phpolars\LazyFrame
mean(): Phpolars\LazyFrame
median(): Phpolars\LazyFrame
mergeSorted(mixed $other, mixed $key, ?bool $maintainOrder = null): Phpolars\LazyFrame
min(): Phpolars\LazyFrame
nUnique(): Phpolars\LazyFrame
nullCount(): Phpolars\LazyFrame
product(): Phpolars\LazyFrame
profile(): array
quantile(float $quantile, ?string $interpolation = null): Phpolars\LazyFrame
remove(mixed ...$predicates): Phpolars\LazyFrame
rename(array $mapping, ?bool $strict = null): Phpolars\LazyFrame
reverse(): Phpolars\LazyFrame
rolling(mixed $indexColumn, string $period, ?string $offset = null, ?string $closed = null, mixed $groupBy = null): Phpolars\LazyGroupBy
schema(): array
select(mixed ...$exprs): Phpolars\LazyFrame
selectSeq(mixed ...$exprs): Phpolars\LazyFrame
shift(?int $n = null, mixed $fillValue = null): Phpolars\LazyFrame
sinkCsv(string $file, ?bool $includeHeader = null, ?string $separator = null, ?string $nullValue = null, ?string $quoteChar = null, ?string $dateFormat = null, ?string $datetimeFormat = null, ?string $timeFormat = null, ?bool $floatScientific = null, ?int $floatPrecision = null, ?bool $decimalComma = null, ?string $lineTerminator = null, ?string $quoteStyle = null, ?bool $includeBom = null): void
sinkIpc(string $file): void
sinkNdjson(string $file): void
sinkParquet(string $file, ?string $compression = null, ?int $compressionLevel = null, ?bool $statistics = null, ?int $rowGroupSize = null): void
slice(int $offset, ?int $length = null): Phpolars\LazyFrame
sort(mixed $by, mixed $descending = null, mixed $nullsLast = null, ?bool $maintainOrder = null): Phpolars\LazyFrame
sql(string $query, ?string $tableName = null): Phpolars\LazyFrame
std(?int $ddof = null): Phpolars\LazyFrame
sum(): Phpolars\LazyFrame
tail(?int $n = null): Phpolars\LazyFrame
topK(int $k, mixed $by, mixed $reverse = null): Phpolars\LazyFrame
unique(mixed $subset = null, ?string $keep = null, ?bool $maintainOrder = null): Phpolars\LazyFrame
unnest(mixed ...$columns): Phpolars\LazyFrame
unpivot(mixed $on = null, mixed $index = null, ?string $variableName = null, ?string $valueName = null): Phpolars\LazyFrame
update(mixed $other, mixed $on = null, ?string $how = null, mixed $leftOn = null, mixed $rightOn = null, ?bool $includeNulls = null, ?string $maintainOrder = null): Phpolars\LazyFrame
var(?int $ddof = null): Phpolars\LazyFrame
width(): int
withColumns(mixed ...$exprs): Phpolars\LazyFrame
withColumnsSeq(mixed ...$exprs): Phpolars\LazyFrame
withRowIndex(?string $name = null, ?int $offset = null): Phpolars\LazyFrame

Phpolars\GroupBy

agg(mixed ...$aggs): Phpolars\DataFrame
all(): Phpolars\DataFrame
count(): Phpolars\DataFrame
first(): Phpolars\DataFrame
getIterator(): Phpolars\GroupIterator
having(mixed ...$predicates): Phpolars\GroupBy
head(?int $n = null): Phpolars\DataFrame
last(): Phpolars\DataFrame
len(?string $name = null): Phpolars\DataFrame
max(): Phpolars\DataFrame
mean(): Phpolars\DataFrame
median(): Phpolars\DataFrame
min(): Phpolars\DataFrame
nUnique(): Phpolars\DataFrame
quantile(float $quantile, ?string $interpolation = null): Phpolars\DataFrame
sum(): Phpolars\DataFrame
tail(?int $n = null): Phpolars\DataFrame

Phpolars\LazyGroupBy

agg(mixed ...$aggs): Phpolars\LazyFrame
all(): Phpolars\LazyFrame
count(): Phpolars\LazyFrame
first(): Phpolars\LazyFrame
getIterator(): Phpolars\GroupIterator
having(mixed ...$predicates): Phpolars\LazyGroupBy
head(?int $n = null): Phpolars\LazyFrame
last(): Phpolars\LazyFrame
len(?string $name = null): Phpolars\LazyFrame
max(): Phpolars\LazyFrame
mean(): Phpolars\LazyFrame
median(): Phpolars\LazyFrame
min(): Phpolars\LazyFrame
nUnique(): Phpolars\LazyFrame
quantile(float $quantile, ?string $interpolation = null): Phpolars\LazyFrame
sum(): Phpolars\LazyFrame
tail(?int $n = null): Phpolars\LazyFrame

From phpstats/phpolars@8487062.