damast.core.polars_dataframe#
Attributes#
Classes#
Module Contents#
- damast.core.polars_dataframe.logger#
- damast.core.polars_dataframe.VAEX_HDF5_ROOT: str = '/table'#
- damast.core.polars_dataframe.VAEX_HDF5_COLUMNS: str#
- damast.core.polars_dataframe.POLARS_TYPE_DICT#
- class damast.core.polars_dataframe.Meta#
Bases:
type- _base_impl: ClassVar[str] = 'polars'#
- __getattr__(attr_name)#
- class damast.core.polars_dataframe.PolarsDataFrame(df: polars.LazyFrame | polars.DataFrame)#
- _polars_dataframe: PolarsDataFrame#
- _dataframe_collected: polars.DataFrame#
- _minmax_cache: dict[str, tuple]#
- property lazyframe: polars.LazyFrame#
The underlying
polars.LazyFrame.This is the sole point of mutation for the wrapped dataframe - assigning to it (rather than e.g. a plain, private instance attribute) is what lets us keep the
collected()cache and thedataframeaccessor consistent with the data that is actually stored, instead of silently returning a stale snapshot after an update.
- classmethod types() dict[str, any]#
- classmethod resolve_type(type_txt: str)#
- classmethod _resolve_parameterized_type(type_txt: str)#
Parse a constructor-call-style dtype repr (e.g. “Datetime(time_unit=’us’)” or “List(Float64)”) back into a polars.datatypes.DataType instance, or return None if type_txt isn’t of that shape.
Uses ast rather than eval to only ever construct a known polars dtype class, with arguments parsed as literals or (recursively) nested dtypes - never arbitrary code.
- classmethod _resolve_arg(node: ast.expr)#
Resolve a single argument node of a parameterized dtype repr: a bare dtype name (e.g. “Float64”), a nested parameterized dtype (e.g. “Datetime(time_unit=’us’)” or “List(Float64)”), a dict/list/tuple of such (e.g. “Struct({‘a’: List(String)})”), or a plain literal (str, int, …).
- property dataframe: PolarsDataFrame#
Allows to access the underlying dataframe directly.
Note
AnnotatedDataFrame behaves like a
polars.LazyFrame, so typically you will not need to access the dataframe through this property.- Returns:
The underlying dataframe
- collected()#
- is_string(column_name: str) bool#
- is_numeric(column_name: str) bool#
- is_datetime(column_name: str) bool#
- is_bool(column_name: str) bool#
- is_date(column_name: str) bool#
- __getitem__(column_name: str)#
Make dataframe subscriptable and behave more like the
pandas.DataFrame.- Parameters:
item – Name of the key when using [] operators
- Returns:
item/column from the underlying vaex.dataframe
- ensure_column(column_name: str)#
Ensure that a column exist, raise ValueError otherwise
- property column_names: list[str]#
Get all column names (without collecting the full dataframe)
- dtype(column_name: str) polars.datatypes.DataType#
Get column dtype (without collecting the full dataframe)
- set_dtype(column_name, representation_type) polars.datatype.DataType#
Set the dtype for a column to the given representation type. Using polars cast functionality :return: The updated object
- rescale(column_name: str, factor: float) None#
Multiply a column’s values by factor in place (e.g. to convert between two equivalent physical units), preserving the column’s existing representation type.
- precompute_minmax(column_names: list[str]) None#
Compute min/max for several columns in a single collect() and cache the results, so that later minmax(column_name) calls for these columns are served from cache instead of each triggering their own collect().
The cache is invalidated automatically whenever lazyframe is reassigned.
- minmax(column_name: str) tuple[any, any]#
Tuple of min and max values of the given column
- categories(column_name: str, max_count: int = 100) list[str]#
- minmax_stats(column_names: list[str]) dict[str, dict[str, any]]#
Tuple of min and max values of the given column
- stats(column_name: str) damast.core.data_description.NumericValueStats#
- __getattr__(attr_name)#
Ensure that this object behaves like a
polars.LazyFrame.- Parameters:
attr_name – Attribute / Name of column
- Returns:
The column data
- __setitem__(key, values)#
Set the column for the annotated dataframe, and allow to behave like the polars.Dataframe.
- Parameters:
key – Column name
value – Value to set the column to
- __len__() int#
Get the length of the (underlying) dataframe.
- Returns:
Length of the dataframe
- equals(other: PolarsDataFrame) bool#
- classmethod open(path: str | pathlib.Path, sep=',') polars.LazyFrame#
- classmethod from_vaex_hdf5(path: str | pathlib.Path) tuple[polars.LazyFrame, damast.core.metadata.MetaData]#
Load hdf5 file and (damast) metadata if found in the file.
- NETCDF_BATCH_SIZE: ClassVar[int] = 100000#
- classmethod import_netcdf(path: list[str | pathlib.Path]) tuple[polars.LazyFrame, dict[str, MetaData]]#
Lazily scan NetCDF files - see
scan_netcdf()- and extract metadata from their CF attributes, see_metadata_from_cf_attributes().
- classmethod scan_netcdf(path: str | pathlib.Path) tuple[polars.LazyFrame, dict[str, tuple[dict, dict]]]#
Lazily scan a NetCDF file as a table with one row per grid cell - the same layout as
xarray.Dataset.to_dataframe(), with the dimensions as leading columns.Nothing is read until the frame is collected. The grid is then read in slices along its first dimension, so memory is bounded by a slice rather than the whole grid, and rows are filtered/projected/limited per slice. Rows in which every data variable spanning the full grid is missing - e.g. the padding of a sparse (entity x time) grid - are dropped.
- Parameters:
path – The NetCDF file
- Returns:
The lazyframe, and variable name -> (CF attributes, xarray encoding)
- static _netcdf_schema(ds) polars.Schema#
Columns and dtypes of
ds.to_dataframe()without reading data: taken from an empty slice, where object columns (strings) cannot be inferred and default to String.
- classmethod _metadata_from_cf_attributes(schema: polars.Schema, variables: dict[str, tuple[dict, dict]], source: str) damast.core.metadata.MetaData | None#
Create metadata for the columns of a loaded NetCDF file from the CF attributes of its variables: ‘long_name’ becomes the description, ‘units’ the unit - if it can be parsed -, and ‘valid_range’/’valid_min’/’valid_max’ the value range of a numeric column.
‘_FillValue’/’missing_value’ are not mapped: xarray already decodes them to NaN (null in polars), while damast’s missing_value is the value used to replace out-of-range values.
- Parameters:
variables – variable name -> (attributes, xarray encoding)
- Returns:
The metadata, or None if no variable carries any of these attributes - so that callers can fall back to searching for a spec file or inferring the metadata
- static _cf_valid_range(attrs: dict, encoding: dict) tuple[Any, Any] | None#
(min, max) from the CF ‘valid_range’, or ‘valid_min’/’valid_max’ attributes - an open side becomes -inf/inf. CF defines them in packed units, so they are unpacked like the data via ‘scale_factor’/’add_offset’, which xarray moves into the variable’s encoding.
- Returns:
The range, or None if the variable declares none
- classmethod import_hdf5(files: str | pathlib.Path | list[str | pathlib.Path]) tuple[polars.LazyFrame, dict[str, MetaData]]#
Import a dataframe stored as HDF5.
This method tries to load using pandas first, then falls back to reading a vaex-based format using pytables.
- classmethod export_hdf5(df: polars.DataFrame | polars.LazyFrame, path: str | pathlib.Path) pathlib.Path#
Export the dataframe as hdf5. Please use only if really needed, otherwise, stick with the default format (parquet).