Skip to content

Releases

v0.3.0

Choose a tag to compare

@randyzwitch randyzwitch released this 23 Oct 14:41
312b28b

What's Changed

Read more

v0.2.0

Choose a tag to compare

@github-actions github-actions released this 21 Sep 20:48
b7e59e8
v0.2.0 — Mojo 1.2 only

Drops Mojo 1.1: a compiled Mojo package loads only in the version that
produced it, so consumers on 1.1 stay on v0.1.3. Built and tested against
1.2.0.dev2026092105.

Since v0.1.3: row-encoded sort keys for fixed-width and string columns
(#108), the scoped worker pool (#103), parallel join output and
partitioned id assembly (#105), and the CSV field-slice decode, bulk byte
copy, UTF-8 narrowing and parallel concat (#107).

Against Polars at 1M rows over that span: sort 6.7x -> 1.7x, join
6.8x -> 4.7x, CSV read 7.8x -> 5.2x.

v0.1.3

Choose a tag to compare

@randyzwitch randyzwitch released this 20 Sep 23:46
2c79432

Parallel grouping, join and sort, plus two timestamp fixes that matter more than any of the speedups for common data.

[workspace]
preview = ["pixi-build"]

[dependencies]
mojo = ">=1.1.0,<1.2"
dataframe_mojo = { git = "https://github.com/randyzwitch/dataframe_mojo.git", tag = "v0.1.3" }

Fixed

  • Datetimes accept an ISO 8601 zone designator: a trailing Z means UTC, and +HH:MM, -HH:MM, +HHMM and +HH convert to UTC. Both previously raised, which rejected the most common datetime spelling in real data (#107).
  • Format directives with no separator between them take their exact width, so %Y%m%d reads 20240228 instead of letting %Y consume six digits and fail (#107).

Changed

At 1,000,000 rows on a 32-core Threadripper, against v0.1.2:

workload v0.1.2 v0.1.3
grouping, ~100k groups 51.7 ms 24.5 ms
join, inner 283 ms 179 ms
sort, two keys 594 ms 345 ms
CSV read 1,260 ms 1,081 ms
  • Grouping partitions rows by key hash so no dictionaries or reduction states are ever merged, which is what made earlier attempts lose at high cardinality (#104).
  • Joins encode both sides' keys one hash bucket at a time instead of building one dictionary over everything (#105).
  • sort, arg_sort, top_k and bottom_k sort one row range per worker and merge the runs, in the same stable order as before for any worker count (#108).
  • CSV parses plain decimal floats in one exact pass rather than validating and then re-parsing (#107).

Added

  • pixi run -e oracle bench-polars: a head-to-head benchmark against Polars on identical inputs with thread counts pinned equal, which produced every number above (#102).

Targets Mojo 1.1. A compiled Mojo package only loads in the Mojo version that produced it, and pixi builds a source dependency with the newest Mojo that [package.host-dependencies] allows rather than the consumer's pin, so each tag targets one Mojo version.

v0.1.2

Choose a tag to compare

@randyzwitch randyzwitch released this 20 Sep 18:00
a83004c

Adds the two APIs another package needs to read data out of a frame efficiently.

[workspace]
preview = ["pixi-build"]

[dependencies]
mojo = ">=1.1.0,<1.2"
dataframe_mojo = { git = "https://github.com/randyzwitch/dataframe_mojo.git", tag = "v0.1.2" }

Arrow buffer access (#91)

unsafe_values(), unsafe_validity() / validity_offset(), unsafe_bytes() / unsafe_offsets() for large_utf8, a non-raising is_valid(i), and to_list(). A consumer reads values in place instead of one tagged AnyValue per element: summing a million-row Float64 column drops from about 3,500 us to about 700 us.

The values pointer is shifted to the window's row 0; the validity bitmap is not, so bit validity_offset() + i describes row i. Null slots hold whatever the buffer holds, as in Arrow, where they are undefined. Nothing converts dtypes.

Row-index grouping (#92)

DataFrame.group_indices(keys) gives the grouping without the aggregation: ids, rows(g), all_rows, sizes, count, and representative(g) for where a group's key values live. Building sub-frames is left to the caller, who may prefer to index the shared buffers directly.

The two compose: hold row indices per group and read values straight from the buffers, without materializing a sub-frame per group.

Targets Mojo 1.1. A compiled Mojo package only loads in the Mojo version that produced it, and pixi builds a source dependency with the newest Mojo that [package.host-dependencies] allows rather than the consumer's pin, so each tag targets one Mojo version.

v0.1.1

Choose a tag to compare

@randyzwitch randyzwitch released this 20 Sep 16:10
4f0415d

The first tag carrying the complete feature set. Prefer this over v0.1.0, which was tagged before bit-packed Boolean columns were known to be missing from main.

[workspace]
preview = ["pixi-build"]

[dependencies]
mojo = ">=1.1.0,<1.2"
dataframe_mojo = { git = "https://github.com/randyzwitch/dataframe_mojo.git", tag = "v0.1.1" }
from dataframe import DataFrame, Series, Column, col

Targets Mojo 1.1. A compiled Mojo package only loads in the Mojo version that produced it, and pixi builds a source dependency with the newest Mojo that [package.host-dependencies] allows rather than the consumer's pin, so each tag targets one Mojo version.

See CHANGELOG.md for the feature set. The API is pre-1.0 and provisional.

v0.1.0

Choose a tag to compare

@randyzwitch randyzwitch released this 20 Sep 15:13
95e10c5

First tagged release, and the first that another Pixi workspace can depend on.

[workspace]
preview = ["pixi-build"]

[dependencies]
mojo = ">=1.1.0,<1.2"
dataframe_mojo = { git = "https://github.com/randyzwitch/dataframe_mojo.git", tag = "v0.1.0" }
from dataframe import DataFrame, Series, Column, col

Targets Mojo 1.1. A compiled Mojo package only loads in the Mojo version that produced it, and pixi builds a source dependency with the newest Mojo that [package.host-dependencies] allows rather than the consumer's pin, so each tag targets one Mojo version.

See CHANGELOG.md for what the library does. The API is pre-1.0 and provisional.