1.5.4 Numeric buffers🔗ℹ

series->f64vector is Series.to_numpy() for a numeric column: an f64vector from ffi/vector, the type foreign code takes. Integers and booleans are cast while copying. A null becomes +nan.0 or the #:null value, and 'error refuses nulls.

> (require ffi/vector)
> (~> df (ref "foo") series->f64vector f64vector->list)

'(1.0 2.0 3.0)

> (f64vector->list (series->f64vector gappy))

'(1.0 +nan.0 3.0)

> (f64vector->list (series->f64vector gappy #:null -1))

'(1.0 -1.0 3.0)

> (series->f64vector gappy #:null 'error)

series->f64vector: null value

  series: "value"

  row: 1

dataframe->f64vector is DataFrame.to_numpy(): one buffer for the selected columns, returned with its row and column counts. It is column-major by default ('fortran, numpy’s order="F") and row-major with 'c.

> (define xy (dataframe (list (series (list 1 2 polars-null) #:name "a")
                              (series '(0.5 1.5 2.5) #:name "b"))))
> (define-values (m nrows ncols) (dataframe->f64vector xy))
> (list nrows ncols (f64vector->list m))

'(3 2 (1.0 2.0 +nan.0 0.5 1.5 2.5))

> (define-values (m/c rows/c cols/c) (dataframe->f64vector xy #:order 'c))
> (f64vector->list m/c)

'(1.0 0.5 2.0 1.5 +nan.0 2.5)

> (define-values (b rows/b cols/b) (dataframe->f64vector xy #:columns '("b") #:null 'error))
> (f64vector->list b)

'(0.5 1.5 2.5)

> (dataframe->f64vector xy #:null 'error)

dataframe->f64vector: null value

  column: "a"

  row: 2

> (dataframe->f64vector df)

dataframe->f64vector: not a numeric column

  column: "bar"

  dtype: 'string

A null becomes NaN here, as in to_numpy, although Polars keeps the two apart (upstream’s Missing data page). Pass 'error where a NaN would be taken for data.

API gaps: no Arrow export (to_arrow, the Arrow C Data Interface); no integer native vectors; a string or temporal column is refused where to_numpy builds an object or datetime64 array. The buffer is garbage-collected memory that Racket CS may move, so hand it only to a foreign call that is not #:blocking?.