phpolars
Examples

phplyr pipelines on Polars

Run one phplyr pipeline on phibble's in-memory DataFrame and on a PolarsTable, check that the results agree, and compare the times.
Uses phpolars phibble phplyr

Inputs

Running

phplyr verbs work on any phibble table. PolarsTable keeps its data in a Polars data frame from phpolars, and phplyr verbs given column names and col() expressions run there as Polars expressions. This page runs the same pipeline on phibble's in-memory DataFrame and on a PolarsTable, over 50,000 sales rows and a 100-row store table.

use Phibble\Polars\PolarsTable;
use function Phplyr\{arrange, col, desc, filter, group_by, left_join, mean, n, sum, summarise};

$sales = PolarsTable::fromPolars(Phpolars\read_parquet('sales.parquet'));
$stores = PolarsTable::fromPolars(Phpolars\read_csv('stores.csv'));

$revenue = $sales
    |> filter(col('units')->gt(0))
    |> left_join($stores, by: 'store')
    |> group_by('region')
    |> summarise(sales: n(), revenue: sum(col('units')->mul(col('price'))), avg_price: mean('price'))
    |> arrange(desc('revenue'));
use Phibble\Polars\PolarsTable;
use function Phplyr\{col, desc, mean, n, phplyr, sum};

$sales = PolarsTable::fromPolars(Phpolars\read_parquet('sales.parquet'));
$stores = PolarsTable::fromPolars(Phpolars\read_csv('stores.csv'));

$revenue = phplyr($sales)
    ->filter(col('units')->gt(0))
    ->leftJoin($stores, by: 'store')
    ->groupBy('region')
    ->summarise(sales: n(), revenue: sum(col('units')->mul(col('price'))), avg_price: mean('price'))
    ->arrange(desc('revenue'))
    ->get();
phibble DataFrame
49.7 ms
PolarsTable
10.3 ms
Speedup
4.8×

Revenue by region (PolarsTable)

region sales revenue avg_price
region-5 9,524 5,909,736.06 59.10
region-4 9,524 5,884,391.58 58.87
region-3 9,524 5,862,222.46 58.63
region-2 9,524 5,834,858.70 58.39
region-1 9,523 5,810,476.55 58.09

Both backends return the same table. phplyr follows dplyr's rules on either one, so a pipeline can move to Polars without changing its results.

A verb given a PHP closure, such as filter(fn ($r) => $r->units > 0), cannot run on Polars threads. PolarsTable copies the table to an in-memory DataFrame, runs the closure there, and copies the result back, so use col() expressions to keep the work in Polars.

Script: site/vignettes/phplyr-on-polars.php in phpstats/phpolars@8487062.