pyantz.jobs.analysis package#
Submodules#
pyantz.jobs.analysis.external module#
Jobs that call user-defined Python functions for data extraction and analysis.
save_from_external_extraction() calls a user function and saves the
returned Polars DataFrame to a Parquet file.
external_simple() calls a function and returns its boolean result.
external_analysis() loads one or more Parquet files into Polars
frames, then passes them as keyword arguments to a user function.
- class ExternalAnalysisParams(*, variable_names_to_parquets: ~collections.abc.Mapping[str, ~pathlib.Path], lazy_or_eager: ~typing.Literal['lazy', 'eager'] | ~collections.abc.Mapping[str, ~typing.Literal['lazy', 'eager']], function_args: list[~typing.Any] = <factory>, function_kwargs: dict[str, ~typing.Any] = <factory>, external_function: ~collections.abc.Callable[..., ~typing.Any])[source]#
Bases:
BaseModelParams to pass to an external function which will perform analysis on data.
- Parameters:
variable_names_to_parquets (Mapping[str, Path])
lazy_or_eager (Literal['lazy', 'eager'] | ~collections.abc.Mapping[str, ~typing.Literal['lazy', 'eager']])
function_args (list[Any])
function_kwargs (dict[str, Any])
external_function (Annotated[Callable[[...], Any], BeforeValidator(func=~pyantz.infrastructure.config.fn_utils.import_function_by_name, json_schema_input_type=PydanticUndefined), PlainSerializer(func=~pyantz.infrastructure.config.fn_utils.serialize_function, return_type=str, when_used=always), WithJsonSchema(json_schema={'type': 'string', 'format': 'base64'}, mode=None)])
- _abc_impl = <_abc._abc_data object>#
- external_function: Callable[..., Any]#
Fully resolved name of the function, e.g.
package.module.function.
- function_args: list[Any]#
Positional arguments to pass directly to the function.
- function_kwargs: dict[str, Any]#
Keyword arguments to pass directly to the function.
- lazy_or_eager: Literal['lazy', 'eager'] | Mapping[str, Literal['lazy', 'eager']]#
If
lazy, all dataframes are scanned lazily (polars LazyFrames); ifeager, all dataframes are read into memory (polars DataFrames); if a mapping, maps each name ofvariable_names_to_parquetsto one of those.
- variable_names_to_parquets: Mapping[str, Path]#
Maps keyword argument names to parquet files; the parquet files are read into polars LazyFrames or DataFrames and passed as keyword arguments to the analysis function.
- class ExternalExtractParams(*, function_args: list[~typing.Any] = <factory>, function_kwargs: dict[str, ~typing.Any] = <factory>, external_function: ~collections.abc.Callable[..., ~polars.dataframe.frame.DataFrame | ~polars.lazyframe.frame.LazyFrame], result_parquet_location: str)[source]#
Bases:
BaseModelParameters to call an external function returning a polars dataframe.
- Parameters:
function_args (list[Any])
function_kwargs (dict[str, Any])
external_function (Annotated[Callable[[...], DataFrame | LazyFrame], BeforeValidator(func=~pyantz.infrastructure.config.fn_utils.import_function_by_name, json_schema_input_type=PydanticUndefined), PlainSerializer(func=~pyantz.infrastructure.config.fn_utils.serialize_function, return_type=str, when_used=always), WithJsonSchema(json_schema={'type': 'string', 'format': 'base64'}, mode=None)])
result_parquet_location (str)
- _abc_impl = <_abc._abc_data object>#
- external_function: Callable[..., DataFrame | LazyFrame]#
Fully resolved name of the function, e.g.
package.module.function; it must return a polars DataFrame or LazyFrame.
- function_args: list[Any]#
Positional arguments to pass directly to the function.
- function_kwargs: dict[str, Any]#
Keyword arguments to pass directly to the function.
- result_parquet_location: str#
Location to save the result from the function.
- class ExternalSimpleParams(*, function_args: list[~typing.Any] = <factory>, function_kwargs: dict[str, ~typing.Any] = <factory>, external_function: ~collections.abc.Callable[..., ~typing.Any])[source]#
Bases:
BaseModelCall an external function.
- Parameters:
function_args (list[Any])
function_kwargs (dict[str, Any])
external_function (Annotated[Callable[[...], Any], BeforeValidator(func=~pyantz.infrastructure.config.fn_utils.import_function_by_name, json_schema_input_type=PydanticUndefined), PlainSerializer(func=~pyantz.infrastructure.config.fn_utils.serialize_function, return_type=str, when_used=always), WithJsonSchema(json_schema={'type': 'string', 'format': 'base64'}, mode=None)])
- _abc_impl = <_abc._abc_data object>#
- external_function: Callable[..., Any]#
Fully resolved name of the function, e.g.
package.module.function.
- function_args: list[Any]#
Positional arguments to pass directly to the function.
- function_kwargs: dict[str, Any]#
Keyword arguments to pass directly to the function.
- external_analysis(params: ExternalAnalysisParams)[source]#
Call some external function with the data loaded into polars.
Each parquet of
variable_names_to_parquetsis loaded and passed to the function as the keyword argument of its name, afterfunction_argsand along withfunction_kwargs. The function’s result is discarded.- Parameters:
params (
ExternalAnalysisParams) – the job’s parameters, validated asExternalAnalysisParams.- Job parameters:
variable_names_to_parquets (Mapping[str, Path]) – keyword argument names mapped to the parquet files to load for them.
lazy_or_eager (str | Mapping[str, str]) –
lazy(LazyFrames),eager(DataFrames), or one of those for each keyword argument name.function_args (list[Any]) – positional arguments for the function. Defaults to none.
function_kwargs (dict[str, Any]) – more keyword arguments for the function. Defaults to none.
external_function (str) – import path of the function to call.
- Returns:
True if the function ran, False if the data can’t be loaded (or a name has no
lazy_or_eagerentry) or the function raises.- Return type:
bool- Raises:
None – failures are logged and reported by returning False.
Example
import polars as pl from pyantz.jobs.analysis.external import external_analysis pl.DataFrame({"a": [1, 2, 3]}).write_parquet("numbers.parquet") # in a configuration, the function is given by its import path def report_total(numbers, label): print(label, numbers["a"].sum()) external_analysis( { "variable_names_to_parquets": {"numbers": "numbers.parquet"}, "lazy_or_eager": "eager", "function_kwargs": {"label": "total:"}, "external_function": report_total, }, lambda job: None, )
total: 6
- external_simple(params: ExternalSimpleParams)[source]#
Call the external function.
- Parameters:
params (
ExternalSimpleParams) – the job’s parameters, validated asExternalSimpleParams.- Job parameters:
function_args (list[Any]) – positional arguments for the function. Defaults to none.
function_kwargs (dict[str, Any]) – keyword arguments for the function. Defaults to none.
external_function (str) – import path of the function to call.
- Returns:
the function’s result if it returns a bool, False if it raises, and True otherwise.
- Return type:
bool- Raises:
None – failures are logged and reported by returning False.
Example
from pyantz.jobs.analysis.external import external_simple def submit(job): pass for args in ([1, 1], [1, 2]): params = {"external_function": "operator.eq", "function_args": args} print(external_simple(params, submit))
True False
- save_from_external_extraction(params: ExternalExtractParams)[source]#
Call a user defined function and save the results off.
While the user could directly call their function, the utility of this function is saving it in the parquet file, allowing the user to ignore the file system fun. Missing parent directories of the parquet are created.
- Parameters:
params (
ExternalExtractParams) – the job’s parameters, validated asExternalExtractParams.- Job parameters:
function_args (list[Any]) – positional arguments for the function. Defaults to none.
function_kwargs (dict[str, Any]) – keyword arguments for the function. Defaults to none.
external_function (str) – import path of the function, which must return a polars DataFrame or LazyFrame.
result_parquet_location (str) – parquet file to save the result to.
- Returns:
True if the result was saved, False if the function raises, returns something other than a dataframe, or the parquet can’t be written.
- Return type:
bool- Raises:
None – failures are logged and reported by returning False.
Example
import polars as pl from pyantz.jobs.analysis.external import save_from_external_extraction save_from_external_extraction( { "external_function": "polars.DataFrame", "function_kwargs": {"data": {"a": [1, 2, 3]}}, "result_parquet_location": "out/extracted.parquet", }, lambda job: None, ) print(pl.read_parquet("out/extracted.parquet")["a"].to_list())
[1, 2, 3]
pyantz.jobs.analysis.simple module#
Simple columnar operations on Parquet data files.
columnar_operation() applies an arithmetic operation between two
columns and stores the result in a new column.
join_parquets() performs a Polars join between two Parquet files and
writes the output to a third file.
- class ColumnarOperationParameters(*, source_parquet_file: Path, result_parquet_file: str, left_col: str, right_col: str, result_col: str, operation: Literal['+', '-', '*', '/'])[source]#
Bases:
BaseModelPerform an operation and save the resulting dataframe in a parquet.
- Parameters:
source_parquet_file (Path)
result_parquet_file (str)
left_col (str)
right_col (str)
result_col (str)
operation (Literal['+', '-', '*', '/'])
- _abc_impl = <_abc._abc_data object>#
- left_col: str#
Column on the left side of the expression.
- operation: Literal['+', '-', '*', '/']#
Operation to be performed between the two columns.
- result_col: str#
Column to save the results.
- result_parquet_file: str#
Location to save the results after performing the operation.
- right_col: str#
Column on the right side of the expression.
- source_parquet_file: Path#
Parquet file to read dataframe from for these operations.
- class JoinParquetParams(*, left_parquet: Path, right_parquet: Path, how: Literal['inner', 'left', 'right', 'full', 'semi', 'anti', 'cross'] = 'inner', output_parquet: Path, on_: str)[source]#
Bases:
BaseModelParameters to join the dataframes from parquet files.
- Parameters:
left_parquet (Path)
right_parquet (Path)
how (Literal['inner', 'left', 'right', 'full', 'semi', 'anti', 'cross'])
output_parquet (Path)
on_ (str)
- _abc_impl = <_abc._abc_data object>#
- check_file_paths()[source]#
Check that output is not the same as the input file.
- Parameters:
None.
- Returns:
the validated parameters.
- Return type:
Self- Raises:
ValueError – if the output parquet is the left or right parquet.
- how: Literal['inner', 'left', 'right', 'full', 'semi', 'anti', 'cross']#
Supported styles of joins (see polars docs for details).
- left_parquet: Path#
Parquet with tabular data to join, on the left of the join operation.
- on_: str#
Column name to join on.
- output_parquet: Path#
Parquet file to save the results, cannot be the same as left/right.
- right_parquet: Path#
Parquet with tabular data to join, on the right of the join operation.
- OP_MAPPING = {'*': <function Expr.mul>, '+': <function Expr.add>, '-': <function Expr.sub>, '/': <function Expr.truediv>}#
Polars expression method for each operation of
columnar_operation().
- columnar_operation(params: ColumnarOperationParameters)[source]#
Perform a simple operation between two columns.
The source parquet is read lazily, the result of
left_col <operation> right_colis added asresult_col, and the dataframe with the new column is written toresult_parquet_file.- Parameters:
params (
ColumnarOperationParameters) – the job’s parameters, validated asColumnarOperationParameters.- Job parameters:
source_parquet_file (Path) – parquet file to read the dataframe from.
result_parquet_file (str) – parquet file to write the result to.
left_col (str) – column on the left side of the expression.
right_col (str) – column on the right side of the expression.
result_col (str) – column to save the results in.
operation (str) –
+,-,*or/.
- Returns:
True if the result was written, False if the source doesn’t exist, lacks a column, or can’t be read or written.
- Return type:
bool- Raises:
None – failures are logged and reported by returning False.
Example
import os import polars as pl from pyantz.jobs.analysis.simple import columnar_operation assert os.path.exists("test_input.parquet") columnar_operation({ "source_parquet_file": "test_input.parquet", "result_parquet_file": "test_output.parquet", "left_col": "a", "right_col": "b", "result_col": "c", "operation": "+", }, lambda *_: None) result = pl.read_parquet("test_output.parquet") print(result)
shape: (2, 3) ┌─────┬─────┬─────┐ │ a ┆ b ┆ c │ │ --- ┆ --- ┆ --- │ │ i64 ┆ i64 ┆ i64 │ ╞═════╪═════╪═════╡ │ 1 ┆ 3 ┆ 4 │ │ 2 ┆ 4 ┆ 6 │ └─────┴─────┴─────┘
- join_parquets(params: JoinParquetParams)[source]#
Join two dataframes read from a parquet.
The parquets are read lazily and the joined dataframe is streamed into the output parquet. A join doesn’t keep the order of the rows.
- Parameters:
params (
JoinParquetParams) – the job’s parameters, validated asJoinParquetParams.- Job parameters:
left_parquet (Path) – parquet on the left of the join.
right_parquet (Path) – parquet on the right of the join.
how (str) – style of join, one of
inner,left,right,full,semi,antiorcross(see polars’ docs). Defaults toinner.output_parquet (Path) – parquet to save the result to; it can’t be the left or right parquet.
on_ (str) – name of the column to join on.
- Returns:
True if the result was written, False if the join fails (for example, a parquet or column doesn’t exist).
- Return type:
bool- Raises:
None – failures are logged and reported by returning False.
Example
from pyantz import start config = { "jobs": [ { "function": "pyantz.jobs.analysis.simple.join_parquets", "parameters": { "left_parquet": "left.parquet", "right_parquet": "right.parquet", "how": "inner", "output_parquet": "output.parquet", "on_": "idx", }, } ], "submitter": { "type_": "local_proc", "working_directory": ".", }, } start(config) # a join doesn't keep the order of the rows result = pl.read_parquet("output.parquet").sort("idx") print(result)
shape: (2, 3) ┌─────┬─────┬───────┐ │ idx ┆ a ┆ b │ │ --- ┆ --- ┆ --- │ │ i64 ┆ i64 ┆ str │ ╞═════╪═════╪═══════╡ │ 1 ┆ 10 ┆ hello │ │ 4 ┆ 13 ┆ world │ └─────┴─────┴───────┘
Module contents#
Jobs for performing simple data analysis.